A题:算一个模拟题吧,带点字符串处理,貌似写复杂了,搞了一个字典树。
代码:
#include<stdio.h> #include<algorithm> #include<math.h> #include<iostream> #include<string.h> using namespace std; #define Word_Len 1000 #define hash Hash #define Sigma_size 52 struct Trie{ int ch[Word_Len][Sigma_size]; //Word_Len???????????????? ??????????????Sigma_size=26 int Have_word[Word_Len]; //???????????????????? int val[Word_Len]; // ????????????????????????????0????????????????????????????????????????????!=0 int sz ; //?????????? void init() //???????????? { sz = 1; memset(ch, 0, sizeof(ch)); memset(val, 0, sizeof(val)); memset(Have_word, 0, sizeof(Have_word));}//?????? int idx(char c){if(\'a\'<=c && c<=\'z\') return c-\'a\';else return c - \'A\' + 26; } //?????????? int insert(char *s){ //??v???????? s???????????????? int u = 0, len = strlen(s); for(int i = 0; i < len; i++){ int c = idx(s[i]); if(!ch[u][c]) //?????????????????????? ch[u][c] = sz++; u = ch[u][c]; } Have_word[u]++; //??????u?????????????????????????? return u; } int find_word(char *s){ int u = 0, len = strlen(s); bool creat = false; for(int i = 0; i < len; i++){ int c = idx(s[i]); u = ch[u][c]; } return u; } }; Trie ac; struct node{ int kill, help; }p[20]; int num[20],hash[Word_Len]; char s[100], name[100], hehe[100][100]; int main() { int i,j,T,n; //freopen("data.out","w",stdout); scanf("%d",&T); while(T--) { ac.init(); for(i=0;i<10;i++){ scanf("%s",hehe[i]); num[i] = ac.insert(hehe[i]); hash[num[i] ] = i; p[i].kill = p[i].help = 0; } scanf("%d",&n); while(n--){ scanf("%s",s); int m = 0, len = strlen(s); for(i = 0; i< len; i++) if(s[i] == \',\' || s[i] == \')\')m++; for(i=0, j=0;;i++,j++){ if(s[i] == \'(\' || i==len)break; name[j]=s[i]; } name[j] = \'\0\'; p[ hash[ac.find_word(name)] ].kill ++; if(p[ hash[ac.find_word(name)] ].kill == 2) printf("%s Double Kill\n",name); else if(p[ hash[ac.find_word(name)] ].kill == 3) printf("%s Trible Kill\n",name); else if(p[ hash[ac.find_word(name)] ].kill == 4) printf("%s Ultra Kill\n",name); else if(p[ hash[ac.find_word(name)] ].kill == 5) printf("%s Penta Kill\n",name); if(m) { for(i=0;s[i]!=\'(\';i++); i++; j = 0;} while(m) { if(s[i] ==\')\'){ name[j] = \'\0\'; p[ hash[ac.find_word(name)] ].help ++; break; } if(s[i] ==\',\') { i++; name[j] = \'\0\'; p[ hash[ac.find_word(name)] ].help ++; j=0; } else { name[j++] = s[i++]; } } scanf("%s %s",s,name); } for(i=0;i<10;i++) printf("%s %d %d\n",hehe[i], p[i].kill,p[i].help); } return 0; }
B题:字符串水题,找到一个“you"后,把前面的串,后面的串分割出来,然后中间连"we",然后就可以了。
代码:
#include<stdio.h> #include<algorithm> #include<math.h> #include<iostream> #include<string.h> #include<string> using namespace std; int main() { string s; while(getline(cin,s)) { string a="you",b="we"; int p; while((p=s.find(a))!=-1) { string s1=s.substr(0,p); string s2=s.substr(p+a.size()); s=s1+b+s2; } cout<<s<<endl; } return 0; }
C题:表面看起来像一个博弈,递推一下就可以了,不解释。
代码:
#include<stdio.h> #include<algorithm> #include<math.h> #include<iostream> #define N 11000 using namespace std; bool win[N];//???????? int main() { int n, m, i, j, all, Cas = 1; win[1] = true; win[0] = false; while(~scanf("%d %d %d",&all,&n,&m)) { for(i=2;i<=all;i++) { win[i] = false; if(win[i-1] == false)win[i] = true; else if(i>=m && win[i-m] == false)win[i] = true; else if(i>=n && win[i-n] == false)win[i] = true; } printf("Case #%d: ",Cas++); if(win[all])printf("1\n"); else printf("0\n"); } return 0; }
D题:计算几何水题,就是找一一个三角形的费马点,循环少了,然后就rejudge挂了,更改后代码如下。
代码:
#include<iostream> #include<algorithm> #include<string> #include<stdio.h> #include<string.h> #include<math.h> using namespace std; const double eps=1e-7; struct point { double x,y; }; double dist(point a,point b) { double ss=a.x-b.x; double tt=a.y-b.y; return sqrt(ss*ss+tt*tt); } double fun(point a,point b,point c) { point u,v; double step=fabs(a.x)+fabs(a.y)+fabs(b.x)+fabs(b.y)+fabs(c.x)+fabs(c.y); int i,j,k; u.x=(a.x+b.x+c.x)/3; u.y=(a.y+b.y+c.y)/3; while(step>eps) { for(k=0;k<10;k++,step/=2) for(i=-5;i<=5;i++) for(j=-5;j<=5;j++) { v.x=u.x+step*i; v.y=u.y+step*j; if(dist(u,a)+dist(u,b)+dist(u,c)>dist(v,a)+dist(v,b)+dist(v,c)) u=v; } } return dist(u,a)+dist(u,b)+dist(u,c); } int main() { point a,b,c; while(cin>>a.x>>a.y>>b.x>>b.y>>c.x>>c.y)printf("%.2lf\n",fun(a,b,c)); return 0; }
E题:用一点概率的知识,忘记判断m,n大小wa一次,小心一下就可以了,不解释。
代码:
#include<stdio.h> #include<algorithm> #include<math.h> #include<iostream> #include<queue> #include<iomanip> using namespace std; typedef long long ll; int main() { ll m,n; while(cin>>n>>m) { if(m>n){puts("0.00%");continue;} double sum=1.0; for(ll i=1;i<=m;i++) sum*=(n+1-i+0.0)/(n+0.0); sum*=100; cout<<fixed<<setprecision(2)<<sum<<"%"<<endl; } return 0; }
F题:简单搜索,不解释,直接上代码:
#include<stdio.h> #include<algorithm> #include<math.h> #include<iostream> #include<queue> #define N 105 #define inf 10000000 using namespace std; int map[N][N], n, m; int dis[N][N], step[4][2] = {0,1,0,-1,1,0,-1,0}; bool inq[N][N]; bool Inmap(int x,int y){ if(x<0 || x>=n || y<0 || y>=m)return false; return true; } int BFS(){ int i, j; for(i=0;i<n;i++) for(j=0;j<m;j++) dis[i][j] = inf; memset(inq, 0, sizeof(inq)); queue<int>qx, qy; qx.push(0); qy.push(0); dis[0][0] = 0; inq[n-1][m-1] = 1; while(!qx.empty()){ int x = qx.front(), y = qy.front(); qx.pop(); qy.pop(); inq[x][y] = 0; for(i = 0;i < 4; i++) { int nowx = x + step[i][0], nowy = y + step[i][1]; if(!Inmap(nowx, nowy))continue; if(dis[nowx][nowy] > dis[x][y] + map[x][y] + 1) { dis[nowx][nowy] = dis[x][y] + map[x][y] + 1; if(!inq[nowx][nowy]) inq[nowx][nowy] = 1, qx.push(nowx), qy.push(nowy); } } } return dis[n-1][m-1]; } int main() { int i, k, j, Cas = 1; int x, y; while(scanf("%d %d %d",&n,&m,&k) ,n) { memset(map, 0, sizeof(map)); while(k--) { scanf("%d %d",&x,&y); x--, y--; map[x][y] = 1; } printf("%d\n",BFS()); } return 0; }
G题:找出所有的不大于1000000的阶乘数,二进制枚举一下,保存在一个set里,对于每一组输入,查找一下输出答案。
代码:
#include<stdio.h> #include<algorithm> #include<math.h> #include<iostream> #include<string.h> #include<string> #include<set> using namespace std; typedef long long ll; ll a[1000]; int main() { a[0]=1; ll i,j,k,m,n,T; n=1; while(1) { a[n]=a[n-1]*(n+1);n++; if(a[n-1]>1000000)break; } //for(i=0;i<n;i++)cout<<a[i]<<" ";cout<<endl; set<ll> st; for(i=1;i<(1<<n);i++) { ll ret=0; for(j=0;j<n;j++) if((i>>j)&1)ret+=a[j]; st.insert(ret); } cin>>T; while(T--) { cin>>m; if(st.find(m)!=st.end())puts("Yes"); else puts("No"); } return 0; }
H题:枚举。
代码:
#include <cstdio> #define maxn 10001 int main() { int a,b,m,T; scanf("%d",&T); while(T--) { scanf("%d%d%d",&a,&b,&m); int t=2*a%m,tmp=0; double num=0; for(int i=a+a;i<=b+b;++i) { if(i<=a+b)++tmp; else --tmp; if(i%m==t) { num+=tmp; } } m=(b-a+1); printf("%.4lf\n",num/(m*m)); } return 0; }
I题:水题,直接上代码:
#include<stdio.h> #include<algorithm> #include<math.h> #include<iostream> #include<queue> using namespace std; int main() { int i, k, n, T;scanf("%d",&T); while(T--) { scanf("%d",&n); int num = 0; while(n) { num += n&1; n>>=1; } if(num==1){puts("3");continue;} int ans = num / 3; if(num % 3 == 1) ans++; else if(num % 3 == 2)ans += 2; printf("%d\n",ans); } return 0; }
J题:公式流。
代码:
#include<stdio.h> #include<algorithm> #include<math.h> #include<iostream> #include<string.h> #include<string> #include<set> using namespace std; typedef long long ll; int main() { ll n; while(cin>>n)cout<<(n/4*(n/4+1))*2<<endl; return 0; }