OP
\
 A Alphabet Cookies
字符串处理
 思路
统计字母数后比对,保证没有字母不足;
 代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 
 | #include<bits/stdc++.h>using namespace std;
 typedef long long ll;
 int main()
 {
 int n,ap[26];
 string g;
 while(cin>>n)
 {
 memset(ap,0,sizeof ap);
 cin>>g;
 for(int i=0;g[i];i++)
 {
 ap[g[i]-'A']++;
 }
 int f=1;
 cin>>g;
 for(int i=0;g[i];i++)
 {
 ap[g[i]-'A']--;
 if(ap[g[i]-'A']<0)f=0;
 }
 if(f)printf("Yes\n");
 else printf("No\n");
 }
 return 0;
 }
 
 | 
 B Sequential game
模拟
 思路
按要求模拟即可
 代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 
 | #include<bits/stdc++.h>using namespace std;
 typedef long long ll;
 int main()
 {
 string g;
 while(cin>>g)
 {
 int zero=0,one=0;
 if(g[0]=='1')one++;
 else zero++;
 for(int i=1;g[i];i++)
 {
 if(g[i]!=g[i-1])
 {
 swap(one,zero);
 }
 if(g[i]=='1')one++;
 else zero++;
 }
 printf("%d %d\n",zero,one);
 }
 return 0;
 }
 
 | 
 C The Hardest Problem Ever
字符串处理
 思路
按要求操作即可
 思路
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 
 | #include<bits/stdc++.h>using namespace std;
 typedef long long ll;
 int main()
 {
 string g;
 while(cin>>g)
 {
 if(g!="START")break;
 getchar();
 getline(cin,g);
 for(int i=0;g[i];i++)
 {
 if(g[i]>='A'&&g[i]<='Z')
 {
 g[i]=(g[i]-'A'-5+26)%26+'A';
 }
 printf("%c",g[i]);
 }
 printf("\n");
 cin>>g;
 }
 return 0;
 }
 
 | 
 D Dart game
dp
 思路
建立两个dp空间,一个存储使用一倍,两倍和三倍的方案数,另一个存储只使用一倍和三倍的方案数;
这两个再作差即为目标分数的合法方案数,因为只要整个方案中存在使用过两倍的情况,便可以将这个两倍移至最后,方案即合法;
注意DP的细节,不可以在一次循环中同时dp一倍,二倍与三倍,推测是与后效性限制有关;
注:所有的可行值是1-20的1-3倍,和25的1-2倍,想玩的可以去洛圣都体验一下hhh;
 代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 
 | #include<bits/stdc++.h>using namespace std;
 typedef long long ll;
 const ll M=2011;
 int main()
 {
 int a[1100]={0},b[1100]={0};
 a[0]=1,b[0]=1;
 for(int k=1;k<=21;k++)
 {
 if(k==21)k=25;
 for(int kk=1;kk<=3;kk++)
 {
 if(k==25&&kk==3)break;
 for(int i=1;i<=1001;i++)
 {
 if(i>=k*kk)a[i]+=a[i-k*kk];
 if(i>=k*kk&&kk!=2)b[i]+=b[i-k*kk];
 a[i]%=M,b[i]%=M;
 }
 }
 }
 int n;
 while(cin>>n&&n)
 {
 printf("%d\n",(a[n]-b[n]+M)%M);
 }
 return 0;
 }
 
 | 
 E Similar Word
字符串处理
 思路
把一个串在后面加上自身后,循环对比即可;
如果两串长度不同则不可能为相似串;
 代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 
 | #include<bits/stdc++.h>using namespace std;
 typedef long long ll;
 const ll M=2011;
 int main()
 {
 string g,g1;
 int a[26];
 while(cin>>g)
 {
 cin>>g1;
 int f=1;
 if(g==g1)f=0;
 g=g+g;
 if(g.length()/2!=g1.length())f=0;
 int i;
 for(i=0;g1[i];i++)
 {
 if(!g.compare(i,g1.length(),g1))break;
 }
 if(!g1[i])f=0;
 if(f)printf("yes\n");
 else printf("no\n");
 }
 return 0;
 }
 
 | 
 F Post office
中位数
 思路
特别像货仓选址问题;
在O(1)的时间复杂度内确定邮局的位置后,遍历区间求距离和,不会TLE;
 代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 
 | #include<bits/stdc++.h>using namespace std;
 typedef long long ll;
 const ll M=2011;
 int main()
 {
 int n;
 ll pos[1003];
 while(~scanf("%d",&n))
 {
 if(!n)break;
 memset(pos,0,sizeof pos);
 memset(frt,0,sizeof frt);
 for(int i=1;i<=n;i++)
 {
 scanf("%lld",&pos[i]);
 }
 scanf("%d",&n);
 int l,r;
 while(n--)
 {
 scanf("%d%d",&l,&r);
 ll ans=0;
 for(int i=l;i<=r;i++)
 {
 ans+=abs(pos[i]-pos[l+r>>1]);
 }
 printf("%lld\n",ans);
 }
 }
 return 0;
 }
 
 | 
 G Lucky Boy
几何,博弈
 思路
首先确定好统计共线的方法;
对于任意两点,一定共线;
对于每一条直线,我们可以用斜截式定义并用map<pair<double,double>,int>储存,经测试,不存在斜率不存在的直线,无浮点误差影响(数据可加强);
由规则来说,每次操作需要拿走共线的任意个点(≥1)也就是说,如果场上存在三点共线的情况,则a必赢;
如果不存在三点共线的情况,则此时的博弈即为以下状况:
场上存在n个点,a先手,每人次可以拿走1个或2个点,取走最后一个点者赢;
那么此时,如果场上有3n个点,则后手者可以控制使每次场上他拿完后仍剩余3n个点,即先手必输;
如果场上有3*n+1或3*n+2个点,则先手者可以取走1个或2个点,使场上剩余3*n个点,情况即变为先后手对换的上种情况,此时后手必输;
 代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 
 | #include<bits/stdc++.h>using namespace std;
 typedef long long ll;
 const ll M=2011;
 map<pair<double,double>,int>mp;
 pair<ll,ll> p[1003];
 int main()
 {
 int n;
 while(~scanf("%d",&n))
 {
 mp.clear();
 int i,j;
 for(i=1;i<=n;i++)
 {
 scanf("%lld%lld",&p[i].first,&p[i].second);
 }
 int ff=0;
 for(i=1;i<=n&&!ff;i++)
 for(j=i+1;j<=n&&!ff;j++)
 {
 {
 double k=(p[j].second-p[i].second)*1.0/(p[j].first-p[i].first)
 ,b=p[i].second-k*p[i].first;
 if(mp[{k,b}]==1)ff++;
 mp[{k,b}]++;
 }
 }
 if(ff||n%3)printf("a is the lucky boy.\n");
 else printf("b is the lucky boy.\n");
 }
 return 0;
 }
 
 | 
 H Car race game
搜了一下题解,好像还要用到线段树之类的,感觉比较麻烦(懒),以后再来探索吧。
 I Jiulianhuan
数学
 思路
之前也没有玩过,赛后找了好多视频也没搞清楚怎么解的;
最后还是感谢sl大佬找的资料,如下:
来自知乎


高中数学书666;
注:题给数据有一些问题,1005的返回值应该是4260;
 代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 
 | #include<bits/stdc++.h>using namespace std;
 typedef long long ll;
 const ll M=10007;
 int qm(int a,int b)
 {
 int ans=1;
 for(;b;b>>=1)
 {
 if(b&1)ans=ans*a%M;
 a=a*a%M;
 }
 return ans;
 }
 int main()
 {
 int n;
 while(cin>>n)
 {
 cout<<(qm(2,n+1)-2+(n&1)+M)*qm(3,M-2)%M<<endl;
 }
 return 0;
 }
 
 | 
 J The minimum square sum
打表,数学
 思路
个人是ph大佬带我打表找规律,不过他要证一下,大家可以拭目以待hh;
结论可以从AC代码中直接读出来,在此不多赘述了;
 代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | #include<bits/stdc++.h>using namespace std;
 typedef long long ll;
 const ll M=2011;
 int main()
 {
 ll n;
 while(cin>>n)
 {
 if(n==2)printf("2\n");
 else if((n+1>>1)&1)printf("%lld\n",n);
 else printf("%lld\n",n*n*2);
 }
 return 0;
 }
 
 | 
 打表代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 
 | #include<bits/stdc++.h>using namespace std;
 typedef long long ll;
 const ll M=2011;
 int main()
 {
 int i,j,k;
 for(i=3;i<=49;i+=2)
 {
 for(j=1;j<=200;j++)
 {
 for(k=j;k<=200;k++)
 {
 if((j*j+k*k)%i==0){printf("%d %d\n",i,(j*j+k*k));goto aa;}
 else if((j*j+k*k)>i)break;
 }
 }
 aa:
 i=i;
 }
 return 0;
 }
 
 
 | 
 ED
实际上应该有一个 NEFU大一省赛训练3 的,但是那一场自己做得实在太水了,在此仅做标记。