今天做的是吉林的省赛,我们队最后出了六题,其他队都是七题以上,感觉我坑了。
A:Welcome, 2008
这是一道签到题吧,陈兴看完就敲了,顺利一A。
我后面也写了一下:
#include <stdio.h> int main() { int n, h; while(scanf("%d", &n), n) { h = n << 1 | 1; for(int i = 1; i <= h; i ++) { if(i == 1 || i == n + 1 || i == (n << 1 | 1)) { for(int j = 1; j <= n + 1; j ++) printf("*"); printf("\n"); } else { printf("*"); for(int j = 2; j <= n; j ++) printf(" "); printf("*\n"); } } printf("\n"); } return 0; }
B:StockWave
这应该是一道DP,求一个序列中上升下降上升下降这样波动的序列长度
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> using namespace std; const int MAXN = 1 << 10; int f[2][MAXN]; double a[MAXN]; int n, ans; void dp() { ans = 0; f[0][0]=1; f[1][0]=0; for(int i = 1; i < n; i ++) { f[0][i] = 1; f[1][i] = 0; for(int j = 0; j <= i - 1; j ++) { if(a[j] > a[i]) { f[0][i] = max(f[0][i], f[1][j] + 1); } if(a[j] < a[i]) { f[1][i] = max(f[1][i], f[0][j] + 1); } } ans = max(ans, f[1][i]); ans = max(ans, f[0][i]); } if(ans < 3) ans = 0; printf("%d\n", ans); } int main() { while(scanf("%d", &n) != EOF) { for(int i = 0; i < n; i ++) scanf("%lf", &a[i]); dp(); } return 0; }
C:Central Avenue Road
枚举两棵树,并且判断他们连成的直线是否可以将所有的树尽量平均的分开,数目小于等于1就符合条件。
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> const int MAXN = 105; typedef long long LL; const LL INF = 0x7FFFFFFFFFFFFFFFll; LL x[MAXN], y[MAXN]; int lc, rc; LL dis, ans; int main() { int n; while(scanf("%d", &n), n) { for(int i = 0; i < n; i ++) { scanf("%lld%lld", &x[i], &y[i]); } ans = INF; for(int i = 0; i < n - 1; i ++) { for(int j = i + 1; j < n; j ++) { lc = rc = 0; LL bx = x[j] - x[i]; LL by = y[j] - y[i]; for(int k = 0; k < n; k ++) { if(k == i || k == j) continue; LL cx = x[k] - x[i]; LL cy = y[k] - y[i]; LL temp = bx * cy - cx * by; if(temp < 0) { rc ++; } else if(temp > 0) lc ++; } if(abs(lc - rc) > 1) continue; dis = bx * bx + by * by; if(ans > dis) ans = dis; } } double ret = sqrt(double(ans)); printf("%.3f\n", ret); } return 0; }
D:Function Value
A special function f is defined as follows:
f(n)=1 if n=1
f(n)=f(n-1) if n is prime integer.
f(n)=f(k)+1 if n is not prime, and k is the maximal factor of n.
Please calculate the function value for given integer n.
大叔秒掉了这道题:
#include<stdio.h> #include <vector> #include<string.h> #include <math.h> int ans[100000]; bool ishes[100000]; std::vector<int> pri; void init() { int i,j; for(i=2;i<100000;i++) { if(ishes[i])continue; for(j=i*2;j<100000;j+=i) { ishes[j]=true; } } for(i=2;i<100000;i++) { if(!ishes[i])pri.push_back(i); } } int cal(int n) { if(n<100000) { if(ans[n]!=-1)return ans[n]; if(!ishes[n]) { int r=cal(n-1); ans[n]=r; return r; } } int i; int qr=sqrt((double)n); for(i=0;pri[i]<=qr;i++) { if(n%pri[i]==0) { int r=cal(n/pri[i])+1; if(n<100000)ans[n]=r; return r; } } return cal(n-1); } int main() { memset(ans,-1,sizeof ans); ans[1]=1; init(); int n; while(scanf("%d", &n) != EOF) { printf("%d\n",cal(n)); } return 0; }
E:Billboard
这道题也是大叔写的,可惜比赛的时候没过,之后改了一点就过了。妥妥的吉大模板,二分图最优匹配,KM算法。
#include<stdio.h> #include <vector> #include<string.h> #include <math.h> #include <algorithm> #define MAXN 110 #define inf 1000000000 #define _clr(x) memset(x,-1,sizeof(int)*MAXN) int kuhn_munkras(int m,int n,int mat[][MAXN],int * match1,int * match2) { int s[MAXN],t[MAXN],l1[MAXN],l2[MAXN],p,q,ret=0,i,j,k; for(i=0;i<m;i++){ for(l1[i]=-inf,j=0;j<n;j++) l1[i]=mat[i][j]>l1[i]?mat[i][j]:l1[i]; if(l1[i]==-inf)return -1; } for(i=0;i<n;l2[i++]=0); for(_clr(match1),_clr(match2),i=0;i<m;i++){ for(_clr(t),s[p=q=0]=i;p<=q&&match1[i]<0;p++) for(k=s[p],j=0;j<n&&match1[i]<0;j++) if(l1[k]+l2[j]==mat[k][j]&&t[j]<0){ s[++q]=match2[j],t[j]=k; if(s[q]<0) for(p=j;p>=0;j=p) match2[j]=k=t[j],p=match1[k],match1[k]=j; } if(match1[i]<0){ for(i--,p=inf,k=0;k<=q;k++) for(j=0;j<n;j++) if(t[j]<0&&l1[s[k]]+l2[j]-mat[s[k]][j]<p) p=l1[s[k]]+l2[j]-mat[s[k]][j]; for(j=0;j<n;l2[j]+=t[j]<0?0:p,j++); for(k=0;k<=q;l1[s[k++]]-=p); } } for(i=0;i<m;i++) { ret+=mat[i][match1[i]]; } return ret; } char s1[110]; char s2[110]; char * p1,* p2; int n,m; int mat[110][110]; int match1[110],match2[110]; int main() { //freopen("c:\\e.in","r",stdin); //freopen("c:\\m.txt","w",stdout); int T; scanf("%d",&T); getchar(); while(T--) { gets(s1); gets(s2); m=strlen(s1); n=strlen(s2); p1=s1; p2=s2; if(n<m) { std::swap(n,m); std::swap(p1,p2); } int i,j; for(i=0;i<m;i++)for(j=0;j<n;j++) { if(p1[i]==p2[j]) { mat[i][j]=200-abs(i-j); } else mat[i][j]=0; } int r=kuhn_munkras(m,n,mat,match1,match2); int as=0; for(i=0;i<m;i++)if(mat[i][match1[i]]!=0)as++; printf("%d %d\n",as,as*200-r); } return 0; }
F:CivilizationMap
这道题没看,据说很神。
G:What is your level?
这道题很遗憾,想多了,居然想到用线段树去做,突然发现写不了,比赛结束后问了苏犇,他一说我就只能呵呵了。
递推...
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> using namespace std; const int MAXN = 200020; const int MAXD = 405; int p[MAXN][2], score[MAXD][MAXD], level[MAXD][MAXD]; int n; void calc() { level[401][400] = 0, level[400][401] = 0; for(int x = 400; x >= 0; x --) { for(int y = 400; y >= 0; y --) { if(score[x][y] > 0) level[x][y] = max(level[x + 1][y], level[x][y + 1]) + 1; else level[x][y] = max(level[x + 1][y], level[x][y + 1]); } } } void query() { int id, q; scanf("%d", &q); while(q --) { scanf("%d", &id); printf("%d\n", level[p[id][0]][p[id][1]]); } } int main() { int T; scanf("%d", &T); while(T --) { scanf("%d", &n); memset(score, 0, sizeof score); for(int i = 0; i < n; i ++) { scanf("%d%d", &p[i][0], &p[i][1]); score[p[i][0]][p[i][1]] ++; } calc(); query(); } return 0; }
H:LampMatrix
这题是DFS,前面陈兴写了没过,大叔后面又写了一遍过了。
#include<stdio.h> #include<string.h> char mp[12][12]; unsigned ans[12][1<<20]; int msk; int n,m; void dfs(int i,int j,int s,int c,int fr) { if(s==m) { ans[i][c]+=ans[i-1][j]; ans[i][c]%=2008; return; } if(mp[i][s]=='.') { c|=j&(0x3<<2*s); dfs(i,j,s+1,c,fr); } else { int a=(j>>(2*s))&0x3; int d; for(d=1;d<=3;d++) { if(d==a||d==fr)continue; dfs(i,j,s+1,c|(d<<2*s),d); } } } int main() { while(scanf("%d%d", &n, &m) != EOF) { int i; bool hs=false; for(i=1;i<=n;i++) { scanf("%s",mp[i]); int j; for(j=0;j<m;j++) { if(mp[i][j]=='#')hs=true; } } if(!hs) { printf("0\n"); continue; } memset(ans,0,sizeof ans); msk=1<<2*m; ans[0][0]=1; for(i=1;i<=n;i++) { int j; int pi=i-1; for(j=0;j<msk;j++) { if(ans[pi][j]==0)continue; dfs(i,j,0,0,0); } } unsigned r=0; for(i=0;i<msk;i++) { r+=ans[n][i]; r%=2008; } printf("%u\n",r); } return 0; }
I:Digit Game
这题是第二水的题,我敲的还复杂了...
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> using namespace std; const int MAXN = 35; char str1[MAXN], str2[MAXN], str3[MAXN]; int a[MAXN], b[MAXN]; void Minus(char *str1, char *str2, char *str3) { int i, j, i1, i2, tmp, carry; int len1 = strlen(str1), len2 = strlen(str2); char ch; i1 = len1 - 1; i2 = len2 - 1; j = carry = 0; while(i2 >= 0) { tmp = str1[i1] - str2[i2] - carry; if(tmp < 0) { str3[j] = tmp + 10 + '0'; carry = 1; } else { str3[j] = tmp + '0'; carry = 0; } -- i1; -- i2; ++ j; } while(i1 >= 0) { tmp = str1[i1] - '0' - carry; if(tmp < 0) { str3[j] = tmp + 10 + '0'; carry = 1; } else { str3[j] = tmp + '0'; carry = 0; } -- i1; ++ j; } -- j; while(str3[j] == '0' && j > 0) -- j; str3[++ j] = '\0'; for(i = 0, -- j; i < j; ++ i, -- j) { ch = str3[i]; str3[i] = str3[j]; str3[j] = ch; } } bool cmp(const int a, const int b) { return a > b; } int main() { while(scanf("%s", str1) != EOF) { memset(str2, 0, sizeof str2); memset(str3, 0, sizeof str3); int len = strlen(str1); for(int i = 0; i < len; i ++) { a[i] = b[i] = str1[i] - '0'; } sort(a, a + len); sort(b, b + len, cmp); for(int i = 0; i < len; i ++) str1[i] = a[i] + '0'; for(int i = 0; i < len; i ++) str2[i] = b[i] + '0'; Minus(str2, str1, str3); int len3 = strlen(str3); for(int i = 0; i < len3; i ++) printf("%c", str3[i]); printf("\n"); } return 0; }