• 记第一场atcoder和codeforces 2018-2019 ICPC, NEERC, Northern Eurasia Finals Online Mirror


    下午连着两场比赛,爽。

    首先是codeforses,我和一位dalao一起打的,结果考炸了,幸亏不计rating。。


    A Alice the Fan

    这个就是记忆化搜索一下预处理,然后直接回答询问好了,我肯定是傻逼了,还写了这么长,幸亏调处来了。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    
    typedef long long ll;
    const int Maxn=210;
    
    int vis[10][Maxn][Maxn],xi[10][Maxn][Maxn],xj[10][Maxn][Maxn];
    
    void ycl() {
    	for(int i=25;i<=200;i++)
    		for(int j=0;j<=200;j++) {
    			if(j>i) continue;
    			if(i==25&&j<24) vis[1][i][j]=1;
    			else if(i>25&&j==i-2) vis[1][i][j]=1;
    		}
    	for(int i=50;i<=200;i++)
    		for(int j=0;j<=200;j++) {
    			for(int k=0;k<=j&&k<24;k++)
    				if(vis[1][i-25][j-k]) {
    					vis[2][i][j]=1;
    					xi[2][i][j]=25;
    					xj[2][i][j]=k;
    					break;
    				}
    			if(vis[2][i][j]) continue;
    			for(int k=26;k<=i&&k<=j+2;k++)
    				if(vis[1][i-k][j-k+2]) {
    					vis[2][i][j]=1;
    					xi[2][i][j]=k;
    					xj[2][i][j]=k-2;
    					break;
    				}
    		}
    	for(int i=65;i<=200;i++)
    		for(int j=0;j<=200;j++) {
    			for(int k=0;k<=j&&k<14;k++)
    				if(vis[2][i-15][j-k]) {
    					vis[3][i][j]=1;
    					xi[3][i][j]=15;
    					xj[3][i][j]=k;
    					break;
    				}
    			if(vis[3][i][j]) continue;
    			for(int k=16;k<=i&&k<=j+2;k++)
    				if(vis[2][i-k][j-k+2]) {
    					vis[3][i][j]=1;
    					xi[3][i][j]=k;
    					xj[3][i][j]=k-2;
    					break;
    				}
    		}
    	for(int i=65;i<=200;i++)
    		for(int j=25;j<=200;j++) {
    			for(int k=0;k<24;k++)
    				if(vis[3][i-k][j-25]) {
    					vis[4][i][j]=1;
    					xi[4][i][j]=k;
    					xj[4][i][j]=25;
    					break;
    				}
    			if(vis[4][i][j]) continue;
    			for(int k=26;k<=i+2&&k<=j;k++)
    				if(vis[3][i-k+2][j-k]) {
    					vis[4][i][j]=1;
    					xi[4][i][j]=k-2;
    					xj[4][i][j]=k;
    					break;
    				}
    		}
    	for(int i=65;i<=200;i++)
    		for(int j=50;j<=200;j++) {
    			for(int k=0;k<24;k++)
    				if(vis[4][i-k][j-25]) {
    					vis[5][i][j]=1;
    					xi[5][i][j]=k;
    					xj[5][i][j]=25;
    					break;
    				}
    			if(vis[5][i][j]) continue;
    			for(int k=26;k<=i+2&&k<=j;k++)
    				if(vis[4][i-k+2][j-k]) {
    					vis[5][i][j]=1;
    					xi[5][i][j]=k-2;
    					xj[5][i][j]=k;
    					break;
    				}
    		}
    	for(int i=75;i<=200;i++)
    		for(int j=0;j<=200;j++) {
    			for(int k=0;k<=j&&k<24;k++)
    				if(vis[2][i-25][j-k]) {
    					vis[6][i][j]=1;
    					xi[6][i][j]=25;
    					xj[6][i][j]=k;
    					break;
    				}
    			if(vis[6][i][j]) continue;
    			for(int k=26;k<=i&&k<=j+2;k++)
    				if(vis[2][i-k][j-k+2]) {
    					vis[6][i][j]=1;
    					xi[6][i][j]=k;
    					xj[6][i][j]=k-2;
    					break;
    				}
    		}
    	for(int i=75;i<=200;i++)
    		for(int j=25;j<=200;j++) {
    			for(int k=0;k<24;k++)
    				if(vis[6][i-k][j-25]) {
    					vis[7][i][j]=1;
    					xi[7][i][j]=k;
    					xj[7][i][j]=25;
    					break;
    				}
    			if(vis[7][i][j]) continue;
    			for(int k=26;k<=i+2&&k<=j;k++)
    				if(vis[6][i-k+2][j-k]) {
    					vis[7][i][j]=1;
    					xi[7][i][j]=k-2;
    					xj[7][i][j]=k;
    					break;
    				}
    		}
    }
    
    int main() {
    //	freopen("test.in","r",stdin);
    	int t,x,y;
    	scanf("%d",&t);
    	ycl();
    	while(t--) {
    		scanf("%d%d",&x,&y);
    		if(!(vis[6][x][y]||vis[7][x][y]||vis[5][x][y]||vis[6][y][x]||vis[7][y][x]||vis[5][y][x])) {
    			puts("Impossible");
    			continue;
    		}
    		if(vis[6][x][y]) {
    			puts("3:0");
    			int tx=xi[6][x][y],ty=xj[6][x][y];
    			printf("%d:%d ",tx,ty);
    			x-=tx,y-=ty;
    			tx=xi[2][x][y],ty=xj[2][x][y];
    			printf("%d:%d ",tx,ty);
    			x-=tx,y-=ty;
    			printf("%d:%d
    ",x,y);
    			continue;
    		}
    		if(vis[7][x][y]) {
    			puts("3:1");
    			int tx=xi[7][x][y],ty=xj[7][x][y];
    			printf("%d:%d ",tx,ty);
    			x-=tx,y-=ty;
    			tx=xi[6][x][y],ty=xj[6][x][y];
    			printf("%d:%d ",tx,ty);
    			x-=tx,y-=ty;
    			tx=xi[2][x][y],ty=xj[2][x][y];
    			printf("%d:%d ",tx,ty);
    			x-=tx,y-=ty;
    			printf("%d:%d
    ",x,y);
    			continue;
    		}
    		if(vis[5][x][y]) {
    			puts("3:2");
    			int tx=xi[5][x][y],ty=xj[5][x][y];
    			printf("%d:%d ",tx,ty);
    			x-=tx,y-=ty;
    			tx=xi[4][x][y],ty=xj[4][x][y];
    			printf("%d:%d ",tx,ty);
    			x-=tx,y-=ty;
    			int ttx=xi[3][x][y],tty=xj[3][x][y];
    			x-=ttx,y-=tty;
    			tx=xi[2][x][y],ty=xj[2][x][y];
    			printf("%d:%d ",tx,ty);
    			x-=tx,y-=ty;
    			printf("%d:%d ",x,y);
    			printf("%d:%d
    ",ttx,tty);
    			continue;
    		}
    		if(vis[5][y][x]) {
    			puts("2:3");
    			swap(x,y);
    			int tx=xi[5][x][y],ty=xj[5][x][y];
    			printf("%d:%d ",ty,tx);
    			x-=tx,y-=ty;
    			tx=xi[4][x][y],ty=xj[4][x][y];
    			printf("%d:%d ",ty,tx);
    			x-=tx,y-=ty;
    			int ttx=xi[3][x][y],tty=xj[3][x][y];
    			x-=ttx,y-=tty;
    			tx=xi[2][x][y],ty=xj[2][x][y];
    			printf("%d:%d ",ty,tx);
    			x-=tx,y-=ty;
    			printf("%d:%d ",y,x);
    			printf("%d:%d
    ",tty,ttx);
    			continue;
    		}
    		if(vis[7][y][x]) {
    			puts("1:3");
    			swap(x,y);
    			int tx=xi[7][x][y],ty=xj[7][x][y];
    			printf("%d:%d ",ty,tx);
    			x-=tx,y-=ty;
    			tx=xi[6][x][y],ty=xj[6][x][y];
    			printf("%d:%d ",ty,tx);
    			x-=tx,y-=ty;
    			tx=xi[2][x][y],ty=xj[2][x][y];
    			printf("%d:%d ",ty,tx);
    			x-=tx,y-=ty;
    			printf("%d:%d
    ",y,x);
    			continue;
    		}
    		if(vis[6][y][x]) {
    			puts("0:3");
    			swap(x,y);
    			int tx=xi[6][x][y],ty=xj[6][x][y];
    			printf("%d:%d ",ty,tx);
    			x-=tx,y-=ty;
    			tx=xi[2][x][y],ty=xj[2][x][y];
    			printf("%d:%d ",ty,tx);
    			x-=tx,y-=ty;
    			printf("%d:%d
    ",y,x);
    			continue;
    		}
    	}
    	return 0;
    }
    

    E Easy Chess

    这道题我的构造方法就是对于63步直接打个表,否则的话就让他一步一步走,从第一层到第六层走,如果这时剩余的步数为2,那么直接向上再向右,直接到达终点。

    然后就到了a7,然后走法就是上右下右循环,还是如果剩余步数为2,直接到终点就好了。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    
    typedef long long ll;
    const int Maxn=110000;
    
    int main() {
    //	freopen("test.in","r",stdin);
    	int n;
    	scanf("%d",&n);
    	if(n==63) puts("a1 b1 c1 d1 e1 f1 g1 h1 h2 g2 f2 e2 d2 c2 b2 a2 a3 b3 c3 d3 e3 f3 g3 h3 h4 g4 f4 e4 d4 c4 b4 a4 a5 b5 c5 d5 e5 f5 g5 h5 h6 g6 f6 e6 d6 c6 b6 a6 a7 a8 b8 b7 c7 c8 d8 d7 e7 e8 f8 f7 h7 g7 g8 h8");
    	else {
    		printf("a1 ");
    		int x=1,y=1;
    		while(n!=2) {
    			n--;
    			if(x&1)
    				if(y==8) x++;
    				else y++;
    			else
    				if(y==1) x++;
    				else y--;
    			printf("%c%d ",y+'a'-1,x);
    			if(x==7) break;
    		}
    		if(n==2) {
    			if(y==8) printf("h7 h8
    ");
    			else printf("%c8 h8
    ",y+'a'-1);
    		}
    		else {
    			while(n!=2) {
    				n--;
    				if(y&1)
    					if(x==7) x++;
    					else y++;
    				else
    					if(x==8) x--;
    					else y++;
    				printf("%c%d ",y+'a'-1,x);
    			}
    			if(x==8) printf("g8 h8
    ");
    			else printf("h7 h8
    ");
    		}
    	}
    	return 0;
    }
    

    F Fractions

    这个题的话就是求若干的分数相加等于(frac{n-1}{n}),其中分母不能等于n,分子必须是正的。

    那么原来分数是(frac{a_i}{b_i}),那么可以化成(frac{a_ifrac n {b_i}}{n}),那么我们令新的(b_i)等于(frac{n}{b_i}),所求即为若干的(a_i)(b_i)相乘,和为n-1。

    先对n分解质因数,如果质因数个数为1,那么一定不行。

    否则,设a,b分别是它的不同的质因数,可以用扩欧求出来x,y使得(ax+by=n-1)

    那么一定存在下面的式子:

    (aequiv (n-1)x^{-1}(mod y))

    那么一定存在一组解使得(0<a<y),又(xyle n),那么(ax<n),因为(ax e n-1),所以(ay<n-1),所以(by>0),所以(b>0)

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    
    typedef long long ll;
    const int Maxn=110000;
    
    void gcd(ll x,ll y,ll &a,ll &b) {
    	if(y==0) {
    		a=1;
    		b=0;
    		return;
    	}
    	gcd(y,x%y,b,a);
    	b-=x/y*a;
    }
    
    int main() {
    //	freopen("test.in","r",stdin);
    	ll n,num1=0,num2=0;
    	scanf("%I64d",&n);
    	ll temp=n-1;
    	for(ll i=2;i*i<=n;i++)
    		if(n%i==0) {
    			if(num1) {
    				num2=i;
    				break;
    			}
    			num1=i;
    			while(n%i==0) n/=i;
    		}
    	if(n!=1&&num1&&!num2) num2=n;
    	if(num2==0) {
    		puts("NO");
    		return 0;
    	}
    	ll a,b;
    	gcd(num1,num2,a,b);
    	a*=temp;b*=temp;
    	if(a>0) {
    		ll temp=a/num2;
    		a%=num2;
    		b+=num1*temp;
    	}
    	else {
    		ll temp=b/num1;
    		b%=num1;
    		a+=num2*temp;
    	}
    	puts("YES
    2");
    	printf("%I64d %I64d
    ",a,(temp+1)/num1);
    	printf("%I64d %I64d
    ",b,(temp+1)/num2);
    	return 0;
    }
    

    G Guest Student

    这道题并不是我做的啊,听说是枚举?

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int n,tot,t,a[10];
    int work(int p){
    	int m=n;
    	for(int i=p;i<=7;i++){
    		m-=a[i];
    		if(m==0) return i-p+1;
    	}
    	int ans=7-p+1;
    	int x=m/tot,y=m%tot;
    	if(y==0) x--,y=tot;
    	ans+=x*7;
    	for(int i=1;i<=7;i++){
    		y-=a[i];
    		if(y==0) return ans+i;
    	}
    }
    int main(){
    //	freopen("1.in","r",stdin);
    	scanf("%d",&t);
    	while(t--){
    		int ans=0x7fffffff;
    		scanf("%d",&n);
    		tot=0;
    		for(int i=1;i<=7;i++){
    			scanf("%d",&a[i]);
    			tot+=a[i];
    		}
    		for(int i=1;i<=7;i++)
    			if(a[i]==1)
    				ans=min(ans,work(i));
    		printf("%d
    ",ans);
    	}
    }
    

    L Lazyland

    傻逼题,不说了。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    
    typedef long long ll;
    const int Maxn=110000;
    
    int n,k,x,b[Maxn];
    ll ans;
    priority_queue<ll,vector<ll>,greater<ll> >hi;
    priority_queue<int> h[Maxn];
    vector<int> vi[Maxn];
    
    int main() {
    //	freopen("test.in","r",stdin);
    	scanf("%d%d",&n,&k);
    	for(int i=1;i<=n;i++) {
    		scanf("%d",&x);
    		vi[x].push_back(i);
    	}
    	for(int i=1;i<=n;i++)
    		scanf("%d",&b[i]);
    	for(int i=1;i<=k;i++)
    		for(int j=0;j<vi[i].size();j++)
    			h[i].push(b[vi[i][j]]);
    	int num=0;
    	for(int i=1;i<=k;i++)
    		if(h[i].empty()) num++;
    		else {
    			h[i].pop();
    			while(!h[i].empty()) {
    				hi.push(h[i].top());
    				h[i].pop();
    			}
    		}
    	while(num--) {
    		ans+=hi.top();
    		hi.pop();
    	}
    	printf("%I64d",ans);
    	return 0;
    }
    

    别的题目都不会啊orz


    然后是一场atcoder,这还是我第一次打atcoder啊,还是一场ABC,虽然题目这么水,但是我还是考炸了。。

    题解就算了,反正题目这么水。。

  • 相关阅读:
    [LeetCode 220.] 存在重复元素 III
    C++ 构造函数 & 析构函数
    [LeetCode 891.] 子序列宽度之和【hard】
    [LeetCode 447.] Number of Boomerangs
    HJ93 数组分组
    HJ77 火车进站
    [LeetCode 338.] 比特位计数
    线段树
    大数量问题的一般解决方法
    字典树
  • 原文地址:https://www.cnblogs.com/shanxieng/p/10056608.html
Copyright © 2020-2023  润新知