浙江大學第十九屆圖森未來杯大學生程序設計競賽


賽后總結:

 T:這是我們第二次集體去參加學校的比賽,總體來說比上一次去浙江中醫葯校賽成績好一點,也算是看到了我們自己的進步?然后呢,今天比賽,我們分頭看了三道簽到題,E J G,然后彭彭和金姐飛快的A了起來,我。。。看E看了好幾遍才看懂。因為太緊張了,所以看到別人A那么快,然后就很想快速讀懂題意。然后就開始看別的,直到彭彭和我們說A有點像二分圖匹配,然后就開始看A了,然后我們想了一下,m那么大不可能是二分圖,就想別的辦法。最后和金姐講了我的思路,然后就開始操作。於是看起了B,接收到題目意思有點問題,想了快兩個小時也沒想出來。期間金姐也在瘋狂A提交。崩潰啊。然后就看了C,這題也有很多讀題誤區,金姐開始寫了。我再讀了一遍B,發現題意和我之前想的不一樣。。。。啊啊啊然后就和隊友說了,我們就想板子模擬大數中。最后沒時間了,啥都沒做出來。賽后隊內總結了經驗,交流一下以后讀題的分工,還是很有收獲的一場比賽。emmm,加油吧。

 J:今天前三題十分順利,但是在A題上掉進了自己作的坑,瘋狂WA,還好最后A出來了。C題感覺能寫出來,可是時間不夠了,哭~~~還是實力太弱了,繼續努力,下次加油!

   P:看J時,瀏覽前幾行后發現跟素數有關,數據范圍還特別大就放棄了(其實真正的題目在最后三四行)翻了前面的題目。看了榜,發現J題A的很多,重新看回J題才發現真的是道水題,我就直接做了。接着,跟榜看了A,以為是二分圖匹配(然而並不是),就誤導了隊友,慶幸我的隊友不像我……接着幫金姐找A題樣例,找了有、、久,但金姐還是A了!剩下兩個小時,B,C全都有或多或少的題目理解錯誤問題,僵持了很久。后來,在譚總的糾正下,我似乎想出了B題,但來不及了,第一次遺憾。

 

題解:

 

A - Thanks, TuSimple!

 ZOJ - 4090 

題意:有n個男孩和m個女孩,他們要組成舞伴,雙方有身高要求,0表示希望對方比自己矮,1表示希望對方比自己矮。問最后可以組成幾對。

思路:分成4大組。男選1和女選0對應,男選0和女選1對應。看代碼就能懂啦。

#include <bits/stdc++.h>
#include<vector>
using namespace std;

#define inf 0x3f3f3f3f
#define mm(a,b) memset(a,b,sizeof(a))
#define ll long long
#define MAXN 1001000
#define mod ((int)1e9+7)
const int N=1e5+50;
using namespace std;
typedef long long int LL;

int work(vector<int>& p,vector<int>& q)
{
    int ans=0;
    sort(p.begin(),p.end());
    sort(q.begin(),q.end());
    while(!p.empty()&&!q.empty())
    {
        if(p.back()>q.back())
            p.pop_back(),ans++;
        q.pop_back();
    }
    return ans;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m;
        scanf("%d %d",&n,&m);
        vector<int>boy,gril;
        int h;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&h);
            boy.push_back(h);
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d",&h);
            gril.push_back(h);
        }
        vector<int>p[2],q[2];
        int qq;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&qq);
            p[qq].push_back(boy[i]);
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d",&qq);
            q[qq].push_back(gril[i]);
        }
        printf("%d\n",work(p[0],q[1])+work(q[0],p[1]));
    }
    return 0;
}
View Code

 

B - Even Number Theory

 ZOJ - 4091 

 

import java.util.*;
import java.math.*;
public class Main {
    public static void main(String[] args) {
        Scanner cin=new Scanner(System.in);
        int T;
        T=cin.nextInt();
        while(T>0)
        {
            T--;
            BigInteger num,ans = BigInteger.valueOf(0);
            num=cin.nextBigInteger();
            while(num.compareTo(BigInteger.valueOf(0))!=0)
            {
                num=num.divide(BigInteger.valueOf(2));
                ans=ans.add(num);
            }
            System.out.println(ans);
        }
    }
}

 

C - Robot Cleaner I

 ZOJ - 4092 

題意:給一個n*m的數字地圖,1表示牆壁,2表示垃圾,0表示空的,還有六種命令,U是向上,D是向下,R向右,L向左,P掃地,I表示什么都不做。

  下指令是這樣的,首先獲取當前位置的坐標(x,y),然后計算一個式子。

  x = 3 * 3 * 3 * 3 * mapp[x][y] + 3 * 3 * 3 * mapp[x - 1][y] + 3 * 3 * mapp[x + 1][y] + 3 * mapp[x][y - 1] + mapp[x][y + 1];

  然后執行第x+1個指令。(指令從1開始存哦)

  在k步內會結束所有操作,然后輸出撿了多少垃圾。

  指令s是有限的,但是k比較大,處於1~10^18。所以如果出現相同的指令或者處於當前位置撿垃圾數量相同的就說明出現循環了,跳出就可以了。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<string>
#include<vector>
#include<ctime>
#include<stack>
using namespace std;
#define inf 0x3f3f3f3f
#define mm(a,b) memset(a,b,sizeof(a))
#define ll long long
#define MAXN 1001000
#define mod ((int)1e9+7)
const int N=751;
using namespace std;
typedef long long LL;
char mmap[2050][2050];
int mapp[2050][2050];
int n,m,a,b,k,ans;
char s[300];
int vis[2050][2050][2];
int Cal(int x,int y)
{
    int xx = 3 * 3 * 3 * 3 * mapp[x][y] + 3 * 3 * 3 * mapp[x - 1][y] + 3 * 3 * mapp[x + 1][y] + 3 * mapp[x][y - 1] + mapp[x][y + 1];
    return xx;
}

void dfs(int x,int y)
{
    if(k==0) return;
    int pos=Cal(x,y);
    char p=s[pos+1];
    if(vis[x][y][1]==ans&&vis[x][y][0]==pos)
        return;
    vis[x][y][0]=pos;
    vis[x][y][1]=ans;
    if(p=='U')
    {
        if(mapp[x-1][y]!=1)
            x--;
    }
    else if(p=='D')
    {
        if(mapp[x+1][y]!=1)
            x++;
    }
    else if(p=='L')
    {
        if(mapp[x][y-1]!=1)
            y--;
    }
    else if(p=='R')
    {
        if(mapp[x][y+1]!=1)
            y++;
    }
    else if(p=='P')
    {
        if(mapp[x][y]==2)
        {
            ans++;
            mapp[x][y]=0;
        }
    }
    else if(p=='I') return;
    k--;
    dfs(x,y);
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ans=0;
        scanf("%d %d",&n,&m);
        scanf("%d %d %d",&a,&b,&k);
        scanf("%s",s+1);
        for(int i=1;i<=n;i++)
        {
            getchar();
            for(int j=1;j<=m;j++)
            {
                scanf("%c",&mmap[i][j]);
                mapp[i][j]=mmap[i][j]-'0';
                vis[i][j][0]=vis[i][j][1]=-1;
            }
        }
        dfs(a,b);
        printf("%d\n",ans);
    }
    return 0;
}
View Code

 

E - Potion

 ZOJ - 4094 

簽到題。題意大致為,制葯需要的材料,一共n種,每種需要的材料為a數組,而baobao擁有的材料為b數組。高級材料可以降級為低級材料,有無限次轉換的機會。問最后可不可以制成葯。

方法:遍歷第一個到倒數第二個,第i個所需要的材料從i+1索取,然后看最后一組滿不滿足條件即可。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<string>
#include<vector>
#include<ctime>
#include<stack>
using namespace std;
#define inf 0x3f3f3f3f
#define mm(a,b) memset(a,b,sizeof(a))
#define ll long long
#define MAXN 101000
#define mod ((int)1e9+7)
int n, k;
int main()
{
    int T;
    scanf("%d", &T);
    while (T--)
    {
        ll a[200], b[200];
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
            scanf("%lld", &a[i]);
        for (int i = 0; i < n; i++)
            scanf("%lld", &b[i]);
        for (int i = 0; i < n - 1; i++)
        {
            if (a[i] - b[i] > 0)
                b[i + 1] = b[i+1]-(a[i] - b[i]);
        }
        if (b[n - 1] >= a[n - 1]) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}
View Code

 

G - Postman

 ZOJ - 4096 

題意:BaoBao要送信,一次能最多拿K封,給你幾個坐標,有正也有負,拿完以后需要回到0點重新拿。問最后最少的距離是多少。

解法:把正坐標和負坐標分開存儲,0點不用管。排序以后,每個數組每次取k封信,距離加上絕對值最大的*2,因為他寄完之后不需要回到原點,就減去最遠的距離。

#include <bits/stdc++.h>

using namespace std;

#define inf 0x3f3f3f3f
#define mm(a,b) memset(a,b,sizeof(a))
#define ll long long
#define MAXN 1001000
#define mod ((int)1e9+7)
const int N=1e5+50;
using namespace std;
typedef long long int LL;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,k;
        scanf("%d %d",&n,&k);
        vector<int> pos,neg;
        int maxx=0;
        ll ans=0;
        for(int i=0;i<n;i++)
        {
            int num;
            scanf("%d",&num);
            maxx=max(maxx,(int)abs(num));
            if(num>0)
                pos.push_back(num);
            else if(num<0)
                neg.push_back(-num);
        }
        sort(pos.begin(),pos.end(),greater<int>());
        sort(neg.begin(),neg.end(),greater<int>());
        for(int i=0;i<pos.size();i+=k)
        {
            //cout<<pos[i]<<endl;
            ans+=pos[i]*2;
        }
        for(int i=0;i<neg.size();i+=k)
        {
            //<<neg[i]<<endl;
            ans+=neg[i]*2;

        }
        ans-=maxx;
        printf("%lld\n",ans);
    }
    return 0;
}
View Code

 

J - Extended Twin Composite Number

 ZOJ - 4099 

題意:給一個正整數n,求兩個合數x,y,滿足x+n=y。

解法:我的想法很傻,從i=4開始遍歷,然后滿足x和y不是素數就好了。。。隊友和我說,如果n是偶數的時候,x=4就好了,n是奇數的話,x=9就可以了。

#include <bits/stdc++.h>

using namespace std;

#define inf 0x3f3f3f3f
#define mm(a,b) memset(a,b,sizeof(a))
#define ll long long
#define MAXN 1001000
#define mod ((int)1e9+7)
const int N=751;
using namespace std;
typedef long long int LL;

bool isnotprime(ll num)
{
    ll a=sqrt(num);
    for(ll i=2;i<=a;i++)
    {
        if(num%i==0)
            return true;
    }
    return false;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ll n;
        scanf("%lld",&n);
        ll a=4,b;
        for(;a<=100;a++)
        {
            b=n+a;
            //cout<<a<<" "<<b<<" "<<n<<endl;
            if(isnotprime(b)&&isnotprime(a))
                break;
        }
        printf("%lld %lld\n",a,b);
    }
    return 0;
}
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM