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;
}
下一个我做出来的题是: Problem E - Casino Advantage 这个题是概率,其实就是递推的概率,不是很难吧,这套题难道我的是读题,赛后看了看这个题,不是很难!!
#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 ,你懂的
Problem H - Let's call SPaDe a SPaDe 这个是我最后做的题,也是一个没有做出来的题
思路不是很难,我用的是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
加油!!