http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=13&page=show_contest&contest=297
最近来看我博客的实在是太少了,当然评论也就更少了,上一个评论还是去年的事,还是我同学评的,囧
周六的时候,也就是4月7号,周六晚上我弄的并不是很认真,我队友他们也没有兴趣,最后的结果就是,我们3个题,当然这个结果我还是比较认同的。
最近喜欢上做套题了,莫名其妙,哎,今天老师还夸了我几句,高兴,但是我知道,我的水平还是有限的,我还得继续努力!加油,come on!嘻嘻
额,我敲了好久,莫名奇妙的弄没了,fuck,懂了,我不应该敲那么多的东东的 简短点
Problem A - Bits and Pieces 思路:判断每一位的情况,然后是第一个不确定的为a为1 b为0 其他位恰好相反,ok最简单的一题
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; int a[40]; int main() { int t; cin >> t; int c,d; while( t-- ) { cin >> c >> d; bool re = 1;;int len = 0; while(c || d) { if((d&1) == 1 && (c&1) == 1) a[len] = 1; else if((d&1) == 1 && (c&1) == 0) a[len] = 2; else if((d&1) == 0 && (c&1) == 1) {re = 0;break;} else if((d&1) == 0 && (c&1) == 0) a[len] = 0; len++; c = c>>1; d = d>>1; } if(re == 0) cout << "-1\n"; else { bool first = 0; int aa = 0,bb = 0; for(int i = len-1;i >= 0;i--) if(a[i] == 1) { aa = aa*2+1; bb = bb*2+1; }else if(a[i] == 0) { aa *= 2; bb *= 2; }else { if(first == 0) { aa = aa*2+1;bb = bb*2; first = 1; }else { aa = aa*2;bb = bb*2+1; } } cout << bb << " " << aa << "\n"; } } return 0; }Problem C - How Many... in 3D! 这个题如果你弄过二维的那个填充的问题的话,你就会想到递推公式,然后解决
这个问题的递推公式是:dp[i] = 2*dp[i-1] + 5*dp[i-2] + 4*dp[i-3] + 4*dp[i-4] + 4*dp[i-5] + ... + 4*dp[0];
ok,这个这个就这么解决了,当然做的时候,三维的东西弄了好久
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; const long long P = 1000000007; long long dp[1000010]; long long re[1000010]; long long re42[1000010]; int main() { dp[0] = 1; dp[1] = 2; dp[2] = 9; dp[3] = 32; re[0] = 1; re[1] = 3; re[2] = 12; re[3] = 44; for(int i = 4;i < 1000004;i++) { dp[i] = (dp[i-1]*2 + dp[i-2]*5 + re[i-3]*4)%P; re[i] = (re[i-1] + dp[i])%P; } int t; cin >> t; while( t-- ) { int n; scanf("%d",&n); cout << dp[n] << "\n"; //printf("%I64d\n",dp[n]); } return 0; }
ok,进入第三题:
Problem D - Pieces and Bits 这个题其实和格雷码有关 当然格雷码大家应该会求吧,不会百度,呵呵,然后就是这个题和格雷码的不同,这个题要求的相邻两个编码应该是有且只有一个相同,ok,我就把偶数位的每一位进行了变化,0->1 1->0;遗憾的是,这个变换之后为什么仍然是1-n的序列,我还是没弄明白,要是有人能弄明白,教教我
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> using namespace std; int code[30]; int code2[30]; void gray2(int len,int n) { memset(code,0,sizeof(code)); for(int i = 0;i < len;i++) if(( n & (1<<i)) != 0) code[i] = 1; code2[len-1] = code[len-1]; for(int i = len-2;i >= 0;i--) code2[i] = code[i] ^ code[i+1]; } int main() { int n,t; cin >> t; while(t--) { cin >> n; for(int i = 0;i < (1<<n);i++) { gray2(n,i); int re = 0; if(i % 2 == 0) for(int j = n-1;j >= 0;j--) code2[j] = 1-code2[j]; //for(int j = n-1;j >= 0;j--) cout << code2[j]; for(int j = n-1;j >= 0;j--) re = re * 2 + code2[j]; printf("%d\n",re); } } return 0; }
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; struct note { long long a,b; }dp[200][200]; long long gcd(long long a,long long b) { while(b) { long long t=a%b; a=b;b=t; } return a; } note add(note a,note b) { note re; re.b = a.b*b.b; re.a = a.a*b.b + b.a*a.b; long long d = gcd(re.a,re.b); re.a = re.a / d; re.b = re.b / d; return re; } note mul(note a,note b) { note re; re.a = a.a * b.a; re.b = a.b * b.b; long long d = gcd(re.a,re.b); re.a = re.a/d; re.b = re.b/d; return re; } int main() { //cout << gcd(1,0) << " " << gcd(0,1); int t; cin >> t; while(t--) { int n,m,k; n = 140; for(int i = 0;i < n;i++) { for(int j = 0;j < n;j++) { dp[i][j].a = 0; dp[i][j].b = 1; } } dp[0][0].a = 1; dp[0][0].b = 1; cin >> n >> m >> k; for(int i = 1;i <= m;i++) { for(int j = 0;j <= k;j++) { note no ; no.a = j;no.b = n; note yes; yes.a = n-j+1;yes.b = n; if(j != 0) dp[i][j] = add( mul(dp[i-1][j] , no) , mul(dp[i-1][j-1],yes) ); else dp[i][j] = mul( dp[i-1][j],no ); } } if(dp[m][k].a == 0) cout << "0\n"; else if(dp[m][k].b == 1) cout << dp[m][k].a << "\n"; else cout << dp[m][k].a << "/" << dp[m][k].b << "\n"; } return 0; }上面的注意分数加减,还得注意long long ,你懂的
思路不是很难,我用的是dp加kmp做的,遗憾的是都是wa,wa了好几次,悲哀,如果有人乐意的话,我贴代码,你们瞅瞅,这个代码是wa的!!
我是百思不得其解啊!!
2012年4.12添加,这个题终于a掉了,原因是那个kmp我并没有认真的学习,我队友给我的模板我就套用上了,结果出了一点小差错!!以至于wa了那么久!!
ok,贴一下可以ac的代码!
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; int dp[200]; char str[200]; int next[200]; char dis[200]; void get_next(int n){ memset(next,0,sizeof(next)); int i,j=-1; next[0]=-1; for(i=1;i<=n;i++){ //dis[j]是不是可以理解为i的前一个字符的next值所指想的字符 while(j>-1&&dis[j+1]!=dis[i])j=next[j]; if(dis[j+1]==dis[i])j++; next[i]=j; } } int get(int start,int end)//前闭后开 { int n = end-start; for(int i = 0;i < n;i++) dis[i] = str[start+i]; dis[n] = '\0'; get_next(n); int l=(n-1)-next[n-1]; //cout << n << " " << l << "\n"; if(n% l == 0) return n/l; else return 1;// 我个大笨蛋居然忘了写这个情况! } int getNum(int t) { int re = 0; while(t) { re++; t = t / 10; } return re; } int main() { //getNum(11); int t; //cin >> t; scanf("%d",&t); //getchar(); while(t--) { scanf("%s",str); //gets(str); int len = strlen(str); dp[0] = 0; dp[1] = 1; for(int i = 2;i <= len;i++) { dp[i] = 1212000; for(int j = 0;j < i;j++) { int t = get(j,i);//t得到的是重复次数 int len = i-j; int ll = len/t; if( len < ll + 2 + getNum(t) ) dp[i] = min( dp[i],dp[j] + len ); else dp[i] = min( dp[i],dp[j] + ll + 2 + getNum(t) ); } } printf("%d\n",dp[len]); } return 0; }
uva上的 这套题,怎么说呢??诡异的地方很多,应该叫trick吧,最后的这个还是没想明白有什么trick
加油!!