这次总结是9月15日到9月17日。
总体来说线段树进展缓慢,参加了两场比赛,也有了新的收获(虽然两场比赛队友都没有到齐)。
一场是西安赛区的,题目贼难,最后一小时才出了最简单的一道题。。。就是s(x)等于x各位上的数字之和,给你一个x,求k,使s(k*x)%233==0。x的范围是1到1000000。刚开始找了半天规律发现并没有用,最后发现答案可以是一个常数,即1000000输出233遍。。。。。。
今天的比赛是青岛赛区的,难度还可以,但是有一个小伙伴未及时赶到,最后只出了三个题。下面介绍一下仅A的这三道题。。。
Chinese Zodiac
题意是给两个生肖的单词,顺着往下查隔着几年。直接暴力找就可以,注意要顺着找,而且要注意输出格式。代码如下:#include<iostream> #include<cmath> #include<string> #include<string.h> #include<algorithm> #include<queue> #include<vector> #include<cstdio> #include<map> #include<cstdio> using namespace std; const double PI=acos(-1.0); const int mx=100100; const long long MOD=1e9+7; int m,n,sum,l,r,h; string a[13]={"end","rat","ox","tiger","rabbit","dragon","snake","horse","sheep","monkey","rooster","dog","pig"}; int main() { string b,c; int i,j; cin>>n; while(n--) { cin>>b>>c; for(i=1;i<=12;i++) if(a[i]==b)break; for(j=1;j<=12;j++) if(a[j]==c)break; if(j==i)cout<<12<<endl; else if(i<j)cout<<j-i<<endl; else cout<<12-i+j<<endl; } }
A Cubic number and A Cubic Number
题意很简单,给你一个素数,判断它是否是两个立方数的差。是输出yes,否则输出no。刚开始想复杂了,结果推错公式了,不过很快改过来了,公式是1+3*(i+1)*i。代码如下:#include<iostream> #include<cmath> #include<string> #include<string.h> #include<algorithm> #include<queue> #include<vector> #include<cstdio> #include<map> #include<cstdio> using namespace std; const double PI=acos(-1.0); const int mx=100100; const long long MOD=1e9; long long m,n,sum,l,r,h; long long a[1000001]; int main() { long long i,j,k,T; char ch[2]; long long x1,x2,x3,y1,y2,y3,x,y; for(i=1;i<=1000000;i++) a[i]=1+3*(i+1)*i; scanf("%d",&T); { for(int cas=1;cas<=T;cas++) { //printf("Case %d:\n",cas); scanf("%lld",&n); for(i=1;i<=1000000;i++) { if(a[i]==n) {printf("YES\n");break;} else if(a[i]>n) {i=1000001;break;}} if(i==1000001) printf("NO\n"); //printf("%d\n",sum); } } return 0; }
The Dominator of Strings
最让我兴奋的就是这道题了。。。因为我用自己学的KMP解决了它。题意很简单,就是给你n个字符串,让你判断其中是否能有一个字符串,把其他的字符串都包含。显然能包含所有其他字符串的就是最长的那一个字符串,只需判断这一个就可以了。用KMP判断是否包含其他所有字符串,另外,如果最长字符串有两个以上,若不全相等,那么一定是不能包含的。直接输出no就可以。存输入的字符串的时候,用char数组会超内存,最后终于想到用map直接映射试了一下,没想到真A了。。。方法:KMP+剪枝。用map存字符串。AC代码如下:
#include<iostream> #include<cmath> #include<string> #include<string.h> #include<algorithm> #include<queue> #include<vector> #include<cstdio> #include<map> #include<cstdio> using namespace std; int mx; int m,n,ans; map<int, string> mm; int f[100001]; int a[100001]; string s2; bool find(int x,int y){ int j=0;string t1=mm[x],t2=mm[y]; for(int i=0;i<a[x];i++) { if(j&&t1[i]!=t2[j]) j=f[j]; if(t1[i]==t2[j]) j++; if(j==a[y]) return 1; } return 0; } void getFail(int x,int y) { f[0]=f[1]=0; string t1=mm[x],t2=mm[y]; for(int i=1;i<a[y];i++) { int j=f[i]; while(j&&t2[i]!=t2[j]) j=f[j]; f[i+1]=t2[i]==t2[j]?j+1:0; } } int main() { int T; int i,j,k,t; int ma; ios::sync_with_stdio(false); while(cin>>t) { while(t--) {cin>>n; ma=0;k=1;ans=0; for(i=1;i<=n;i++) { string s1; cin>>s1; a[i]=s1.length(); mm[i]=s1; if(a[i]>ma) {ma=a[i];ans=1;k=i;} else if(a[i]==ma) { if (mm[i]!=mm[k]) ans++; } } if(ans!=1)cout<<"No"<<endl; else { for(i=1;i<=n;i++) { if(i==k) continue; getFail(k,i); if(!find(k,i)) break; } if(i!=n+1) cout<<"No"; else cout<<mm[k]; cout<<endl; } } } return 0; }看到这道题第一眼的时候想到的就是KMP,看来当时补题没白补。。。最后都快放弃的时候灵机一动想到了用map,看来以后要加强对数据结构中队列、栈、vector、map等的练习和运用了呢。。。
总体来说收获还是有的,虽然队友没到齐,但是也考验了我的个人能力。另外A题求一点在圆外由于c++精度不够,只有JAVA才能A,看来以后得抽出一点时间来学习一下JAVA中的ACM用到的大数据部分了。。。
明天开始向数据结构发起挑战,愿这学期能将数据结构学习的差不多,完成自己为这学期制定的学习计划。(线段树还是感觉比较难,看不懂啊。。。看懂了也不会用啊。。。)