The 2018 ACM-ICPC JiangSu 关于2018年江苏省acm省赛感悟

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33193309/article/details/81394103

回顾赛已经结束

比赛顺利打铁,热身赛就是铁牌,记得热身赛有个题很坑,暴力水过,当时没暴力写

这次能在自己大校参赛也是相当荣幸了。值得庆幸的是我和我两个队友从始至终都没有放弃

回想第一次参加青岛区域赛,水了一个题,发现做不动,便和队友聊了4小时的天,看了4小时的榜单

这次参加之前就和队友说,不管做的怎么样,不要放弃,做满5小时。

这次回顾赛用了3小时A了4个。怎么说呢,比赛才A俩,有一题java大数不会提交,找不到javawe就是文件。

我发现在比赛好多思路想不到,线上就显得思路很清晰(可能也和英语有关系,回顾赛全程谷歌)

首先我们跟着榜单走,先开的D. Persona5

D队友直接排列组合一波推出公式,我上手写代码,取模是个问题。之前做过的,对质数取模费马小定理OK

这题无脑ER了两次,这怪我,一直没用longlong。。我总感觉int够用,想太多...

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const long long mod=1000000007;
long long ksm(long long len,long long x){
	long long temp=x;
	long long sum=1;
	while(len){
		if(len&1) sum=(sum*temp)%mod;
		temp*=temp;
		temp%=mod;
		len=len>>1;
	}
	return sum;
}
long long getjc(long long n){
	long long sum=1;
	for(int i=2;i<=n;i++){
		sum=(sum*i)%mod;
	}
	return sum;
}
int main(){
	int n;
	while(scanf("%d",&n)!=EOF){
		long long sum=0;
		long long sum2=1;
		for(int i=0;i<n;i++){
			long long num;
			scanf("%lld",&num);
			sum2=(sum2*getjc(num))%mod;
			sum+=num;
		}
		sum=getjc(sum)%mod;
		//cout<<sum<<endl;
		long long ksmsum=ksm(mod-2,sum2)%mod;
		printf("%lld\n",(ksmsum*sum)%mod);
	}
	return 0;
} 

A完这题并没有进铜,自己太无脑。。。

然后跟着榜单开A. Plague Inc

我们没拿奖信心被击垮就是这题,浪费时间也全在这了

这题我看了下题目,首先感觉水题,广搜O(n*m)就可以了

不然不然。。。贼他妈,死就死在这里,我提交了2次超时,实在不知道如何能简化了

再看一下榜单,别人第一题都不是一次AC,我就想肯定还能优化,我连原来写了两个O(n*m)的for循环硬给压缩成一个循环

还是超时,实在受不了,疯狂调试,问题到底出在哪。最后提交了8次,还是超时

真的,当时我的心呀。。队友也没有泄气,帮我看了下代码问题。无从优化,这时候大约进行2个多小时了

先开别的题吧。。然后去做了别的题,在最后一个小时的时候,我回过来又做了一遍这个题

我想反正都这样了,破罐子破摔,我写个暴力求曼哈顿距离试试。O(n*m*k)竟然过了

第一次提交也就是第九次提交,答案错误,并没有提示超时,这时我一个队友去了个厕所,我对另一个队友说,等他回来给他个惊喜。我检查了代码,忘记每次初始化,提交。。第十次A.....真的,死就死在这题上了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef struct node{
	int x,y;
}node; 
const int INF=1<<29;
int main(){
	node no[20];
	int n,m;
	while(scanf("%d%d",&n,&m)!=EOF){
		int k;
		scanf("%d",&k);
		static int len[2010][2010]={0};
		for(int i=0;i<=n;i++){
			for(int j=0;j<=m;j++) len[i][j]=INF;
		}
		for(int i=0;i<k;i++){
			int x,y;
			scanf("%d%d",&no[i].x,&no[i].y);
		}
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				for(int l=0;l<k;l++){
					len[i][j]=min(len[i][j],abs(i-no[l].x)+abs(j-no[l].y));
				}
			}
		}
		int maxn=0;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				maxn=max(maxn,len[i][j]);
			}
		}
		int flag=1;
		for(int i=1;i<=n&&flag;i++){
			for(int j=1;j<=m&&flag;j++){
				if(len[i][j]==maxn){
					printf("%d %d\n",i,j);
					flag=0;
				}
			}
		}
	}
	return 0;
} 

这时候又送来一个气球。。。还剩半小时左右,我们心底知道,已经拿不到奖了,从始至终真的没放弃

我们看了 J. Set

看榜单很多人过,这题绝对没有想象的那么难。。我一个队友计算前几项,交叉划一下无意中发现了规律

(其实这题我在放弃第一题之后就在看着题,我想这找规律,奈何我求前几项求错了。。。心痛)

队友写下规律,看了下数据贼大,这时候只能把我java搬出来了,大数忘记了不少写出来很麻烦

写了很长时间,写结束还有大约3分钟,然后测试下都是对的,问题来了。。。。没交过java,我找不到java的提交文件呀!!!前后提交了.class还有包,就是找不到.java文件。比赛结束,还是只过了两个,时间多一点肯定可以找到,当时保存就没在意。我把代码拷贝下来,这次回顾赛提交,顺利AC


import java.math.BigInteger;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BigInteger n;
		Scanner sc=new Scanner(System.in);
		while(sc.hasNext()) {
			BigInteger sum=new BigInteger("1");
			int len=sc.nextInt();
			BigInteger fz=new BigInteger("1");
			BigInteger q=new BigInteger("1");
			for(int i=2;i<=len;i++) {
				BigInteger temp=BigInteger.valueOf(i);
				fz=(fz.multiply(temp.add(q)).add(temp));
				
			}
			System.out.println(fz);
		}

	}

}

倒霉。。其实就算这个提交成功,我们也没有铜,就是感觉很可惜呀

期间我们还看了B. Array

当时真的脑子抽掉了。。。想打表看一下有没有规律,我们三竟然都在手算,竟然完全忘记有个电脑直接打表。。。

算到5就算不下去了,太费劲了,放弃了当时

这个回顾赛,我打了个表,前面几行的规律都是a[i][j-1]+a[i-1][j]

打表到后面几行8,9,10的时候,发现这个规律不对,还要减去a[i-1][j-i]。。

自己测试下,规律就是这个!!!!!啊啊啊啊啊啊,为什么比赛我们要手算呀

第一感觉直接打个5000*5000的表,提交,发现超内存。。。被限制了

然后调一下, 发现也就两行数据有用,换成滚动数组2*5000,交了一发,超时。。

哎呦,想着,奇了怪了,我规律好不容易找到了,你给我来个超时和超内存???

发现可以离线一下,用个结构体保存,可以少一次循环哦~~~~

emmmmmmmmmm,开始操作,第一次出现问题就是因为输出的时候第一行我没输出E了一发

然后改一下,成功AC。。。我他妈,心里真的是.......

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef struct node{
	int n,k;
	int index;
	long long sum;
}node;
const long long mod=1000000007;
bool cmp(node n1,node n2){
	if(n1.n==n2.n) return n1.k<n2.k;
	return n1.n<n2.n;
}
bool cmp1(node n1,node n2){
	return n1.index<n2.index;
}
int main(){
	int n,k;
	node no[5001];
	int cnt=0;
	while(scanf("%d%d",&no[cnt].n,&no[cnt].k)!=EOF){
		no[cnt].index=cnt;
		cnt++;
	//	if(cnt==1) break;
	}
	sort(no,no+cnt,cmp);
	long long a[2][5001]={0};
	a[0][0]=1;
	a[1][0]=1;
	a[1][1]=1;
	int len=0;
	for(int i=0;i<cnt;i++){
		if(no[i].n!=1){
			len=i;
			break;
		}
	}
	for(int i=2;i<=5000;i++){
		for(int j=0;j<=5000;j++){
			int fz=(j-i>=0?a[i%2][j-i]:0)%mod;
			a[(i+1)%2][j]=(a[(i+1)%2][j-1]%mod+a[i%2][j]-fz+mod)%mod;
			if(j==0) a[(i+1)%2][j]=1;
			if(no[len].n==i&&no[len].k==j){
				no[len].sum=a[(i+1)%2][j]%mod;
				//cout<<i<<" "<<j<<" "<<a[(i+1)%2][j]<<" "<<a[(i)%2][j]<<endl;
				len++;
			}
		} 
	}
	//	printf("%lld\n",a[(n+1)%2][k]%mod);
	sort(no,no+cnt,cmp1);
	for(int i=0;i<cnt;i++){
		if(no[i].n==1){
			if(no[i].k==0) printf("1\n");
			else printf("0\n");
		}
		else
		printf("%lld\n",no[i].sum);
	}
	return 0;
}

其实也怪自己比赛经验不足,容易紧张很多想不到。包括我们队友,我们三竟然开始手算打表,这让前面的计算机怎么想?

结果就这样。。比赛A了两道,一道写对没提交成功。回顾赛A了4到。顺利打铁!

总的来说,这次跟队友坚持到了最后一刻,也没说想放弃,不像上次划水花了4小时,如果还有下次比赛,加油

欢迎大家加入 早起学习群,一起学习一起进步!(群号:642179511)

猜你喜欢

转载自blog.csdn.net/qq_33193309/article/details/81394103
今日推荐