2014年7月23日比赛题目

UVA 12720 Algorithm of Phil

Phil is learning a new algorithm which wasn't taught in his algorithms classes. However, he is not sure whether he implemented it the right way, so he would really appreciate if you could implement it so that he can compare the outputs.

The algorithm starts with a binary string A and an empty string S. The algorithm consists of multiple steps. In each step, A and S are modied as follows:

·If the number of bits in A is odd, then the middle bit of A is added to the end of S and removed from A.

·If the number of bits in A is even, then both middle bits of A are compared. The bigger one (anyone in case of a tie) is added to the end of S and removed from A.

·If after some step the string A gets empty, the algorithm terminates. The algorithm's return is the decimal representation of the number represented by S.

A bit a is bigger than a bit b if a is 1 and b is 0.

Input

The rst line contains T (T <= 500) | the number of test cases, after this line T test cases follows. Each test case consists of one line containing a binary string A (1 <=|A|<=10^5), representing the algorithm's input.

Output

For each case print a line containing ‘Case #X: Y’, where X is the case number, starting at 1, and Y is the algorithm's return for the given input, modulo 1000000007 (10^9+ 7).

Sample Input

3

00000

0101101

100

Sample Output

Case #1: 0

Case #2: 106

Case #3: 2

【题目大意】

给出一个01串,每次操作:如果该串长度为奇数,取出中间的放到ANS串末尾,如果是偶数,则取出中间两个最大的那个放到ANS末尾,直到给定串为空

【题解】

水题,一开始是用string类型定义给定串的,删除字符就拷贝两次,结果是喜闻乐见的TLE,后来发现根本不!用!删!除!操!作!

【代码】

RunID

User

Problem

Result

Memory

Time

Language

Length

Submit Time

2472432

zhyfzy

A

Accepted

0 KB

108 ms

C++ 4.8.2

914 B

2014-07-23 12:53:34


#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#define MOD 1000000007
#define N 200000
using namespace std;
int i,j,k,n,T,K,len,m,ax;
long long aa;
char temp[N],s[N],ans[N];
int main()
{
	scanf("%d",&T);
	for (K=1;K<=T;K++)
	{
		getchar();
		scanf("%s",s);
		len=strlen(s);
		ans[len]='';
		if (len%2)
		{
			m=(len+1)/2-1;
			ans[0]=s[m];ax=0;
			for (i=1;i<=m;i++)
			{
				if (s[m-i]>s[m+i])
				{
					ans[++ax]=s[m-i];
					ans[++ax]=s[m+i];
				} else
				{
					ans[++ax]=s[m+i];
					ans[++ax]=s[m-i];
				}
			}
		} else
		{
			m=len/2;ax=-1;
			for (i=1;i<=m;i++)
			{
				if (s[m-i]>s[m+i-1])
				{
					ans[++ax]=s[m-i];
					ans[++ax]=s[m+i-1];
				} else
				{
					ans[++ax]=s[m+i-1];
					ans[++ax]=s[m-i];
				}
			}
		}	
		aa=0;
		for (i=0;i<len;i++)
		{
			if (ans[i]=='1') aa=(aa*2+1)%MOD;
			else aa=(aa*2)%MOD;
		}
		printf("Case #%d: %lld
",K,aa);
			
	}
}

UVA 12721 Cheap B-Subsequence

【题目大意】

PDF粘题太麻烦了,就不粘题了

这道题是求给定字母串的子串的最小值

从给定小写字母串中找一个长度为b的子串(各字符位置可以不连续),

每个字母给Q个数对,(Pi,Ci)

子串的值表示为字符的的值的和,我们假定某字符在子串的位置为X,则该字符的值为X/Pi*CiXPi的倍数时加入结果中。

比如

[a]={(2,3),(4,10)}

[b]={(1,4),(7,50)}

[c]={(1,2),(4,20)}

字符串abaabcbc,长度b=4

如果子串为”aabc” (abaabcbc)

第一个a位置为1,不能整除a的任何Pi值,值为0

第二个a位置为2,值为3

第三个b值为33/1*4=12,值为12

第四个c值为44/4*20+4/1*2=28,值为28

所以子串的值为43

现在求字符串的子串的最小值为多少

【题解】

很简单的动态规划,数据规模不大(每个数都小于100),所以三层循环可以胜任

c[i][j]为字母i在子串j位置处的值,通过预处理可以得到数组c的值

f[i][j]为将给定串S的第i位放在子串j位置处的最小值

F[i][j]=min{f[k][j-1]+c[alp][j]}alp为给定串Si位字符,k<i

【代码】

RunID

User

Problem

Result

Memory

Time

Language

Length

Submit Time

2475919

zhyfzy

B

Accepted

0 KB

39 ms

C++ 4.8.2

815 B

2014-07-23 16:27:32

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;
int i,j,k,n,T,alp,K,c[200][200],p,cc,ans,f[200][200],b,m;
char s[200];
int main()
{
	scanf("%d",&T);
	for (K=1;K<=T;K++)
	{
		memset(c,0,sizeof(c));
		memset(f,0x2f,sizeof(f));
		
		getchar();
		s[0]=' ';
		scanf("%s %d",s+1,&b);
		n=strlen(s)-1;
		for (i=1;i<=26;i++)
		{
			scanf("%d",&m);
			for (j=1;j<=m;j++)
			{
				scanf("%d%d",&p,&cc);
				for (k=p;k<=b;k+=p)
				{
					c[i][k]+=k/p*cc;
				}
			}
		}
		
		for (i=0;i<=n;i++) f[i][0]=0;
		ans=1<<30;
		
		for (j=1;j<=b;j++)
		{
			for (i=j;i<=n;i++)
			{
				alp=s[i]-'a'+1;
				for (k=0;k<=i-1;k++)
				{
					f[i][j]=min(f[i][j],f[k][j-1]+c[alp][j]);
				}
			}
		}
		for (i=b;i<=n;i++)
		{
			ans=min(ans,f[i][b]);
		}
		printf("Case #%d: %d
",K,ans);
	}
		
}


UVA 12723 Dudu, the Possum

【题目大意】

冰箱有N层,老鼠在顶端,每次最多向下跳K层,向下跳i层的概率为Pi,每层有多个食物,老鼠只能吃一个,食物的卡路里Ci,j(第i层的第j个食物)与吃该食物的概率Xi,j给定,求老鼠跳到最底层后吃到的食物卡路里的数学期望。

【题解】

模拟,由于到哪一层与食物没有关系,先求出老鼠到每一层的概率,然后用这个概率乘每层食物的期望即可。

每层食物的卡路里的期望就不必要说了吧,卡路里乘上概率再求和

每一层的概率,f[i]=sum{f[i-j]*p[i]}1<=j<=k

【代码】

RunID

User

Problem

Result

Memory

Time

Language

Length

Submit Time

2477328

zhyfzy

D

Accepted

0 KB

73 ms

C++ 4.8.2

703 B

2014-07-23 19:10:43

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;
int i,j,k,n,T,K,q;
double t1,t2,p[1000],qw[1000],f[1000],ans;
int main()
{
	scanf("%d",&T);
	for (K=1;K<=T;K++)
	{
		ans=0;
		scanf("%d%d",&n,&k);
		for (i=1;i<=k;i++)
		{
			scanf("%lf",&p[i]);
		}
		for (i=1;i<=n;i++)
		{
			scanf("%d",&q);
			qw[i]=0;
			for (j=1;j<=q;j++)
			{
				scanf("%lf%lf",&t1,&t2);
				qw[i]+=t1*t2;//qw记录每一层食物的期望
			}
			//printf("qw[%d]= %lf
",i,qw[i]);
		}
		f[1]=1;ans=qw[1];
		for (i=2;i<=n;i++)
		{
			f[i]=0;
			for (j=1;j<=k;j++)
			{
				if (i-j<=0) break;
				f[i]+=f[i-j]*p[j];
			}
			ans+=f[i]*qw[i];
			//printf("f[%d]= %lf
",i,f[i]);
		}
		printf("Case #%d: %.6lf
",K,ans);
	}
}


UVA 12724 Hnelpig Arnde

【题目大意】

N个单词的字典

然后给几个句子,句子中每个单词出去首尾字母都是乱序的,你需要帮忙恢复顺序

【题解】

很水的题目,一种方法是统计单词中字母的个数,当首尾相同是比较各个字母出现次数,如果相同则是一个单词

另一种方法时将单词中的除去首尾的字母排序,只需判断排序后的单词是否相同即可

第二种更快并且好写一些,模拟赛时用的第一种方法,所以代码看起来比较长

【代码】

RunID

User

Problem

Result

Memory

Time

Language

Length

Submit Time

2475104

zhyfzy

E

Accepted

0 KB

92 ms

C++ 4.8.2

1229 B

2014-07-23 15:36:26

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
char *w[101],c,s[101];
int i,j,k,n,T,K,m,f[100],num[100][26],len[100],lens,tt[26];

bool cmp(char *x,char *y)
{
	if (x[0]==y[0]) return x[strlen(x)-1]<y[strlen(y)-1];
	else return x[0]<y[0];
}

bool equals(int x[26],int y[26])
{
	for (int i=0;i<25;i++)
	{
		if (x[i]!=y[i]) return false;
	}
	return true;
}

int main()
{
	scanf("%d",&T);
	for (K=1;K<=T;K++)
	{
		
		
		scanf("%d%d",&n,&m);
		getchar();
		for(i=0;i<n;i++)
		{
			w[i]=new char[101];
			scanf("%s",w[i]);
		}
		sort(w,w+n,cmp);
		for (i=0;i<n;i++)
		{
			if (i==0||w[i][0]!=w[i-1][0]) f[w[i][0]-'a']=i;
			memset(num[i],0,sizeof(num[i]));
			len[i]=strlen(w[i])-1;
			for (j=0;j<=len[i];j++)
			{
				num[i][w[i][j]-'a']++;
			}
		}
		
		printf("Case #%d:
",K);
		getchar();
		for (i=1;i<=m;i++)
		{
			do
			{
				scanf("%s%c",s,&c);
				lens=strlen(s)-1;
				memset(tt,0,sizeof(tt));
				for (j=0;j<=lens;j++)
				{
					tt[s[j]-'a']++;
				}
				for (j=f[s[0]-'a'];w[j][0]==s[0];j++)
				{
					if (lens==len[j]&&w[j][len[j]]==s[lens]&&equals(tt,num[j]))
					{
						printf("%s%c",w[j],c);
						break;
					}
				}
			}while (c==' ');
		}
	}
		
}


UVA 12725 Fat and Orial

【题目大意】

Fat同学做了A次比赛平均分为N,想再做B次比赛平均分涨到M,求这B次比赛的平均分(分数最高为10),不可能达到则输出Impossible

【题解】

水题,ans=((a+b)*m-a*n)/b,注意分数不可能低于0和高于10,因为没有判断低于0的情况wa了一次,还以为是精度问题。。。。T.T

【代码】

RunID

User

Problem

Result

Memory

Time

Language

Length

Submit Time

2477573

zhyfzy

F

Accepted

0 KB

142 ms

C++ 4.8.2

337 B

2014-07-23 19:38:06

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;
int i,j,k,T,K;
double n,m,a,b,tt;
int main()
{
	scanf("%d",&T);
	for (K=1;K<=T;K++)
	{
		scanf("%lf%lf%lf%lf",&n,&m,&a,&b);
		tt=((a+b)*m-a*n)/b;
		if (tt>10||tt<0) printf("Case #%d: Impossible
",K);
		else printf("Case #%d: %.2lf
",K,tt);
	}
}


UVA 12729 Squares Game

【题目大意】

n*m的棋盘,ana往里边放2*2的方块,bob往里边放1*1的方块,anabob轮流放,ana先放,如果ana不能再放就只能让给bob放,最终谁的面积最大谁赢,或者平局

【题解】

开始想的是组合游戏,使用记忆化搜索,但发现并不是,首先,组合游戏一定是只有输赢两种状态,而且由输的状态推出赢的状态,这里都不好推

所以不是组合游戏

......

不妨设n,m都是偶数,每当ana占据一个四格时,bob一定会破坏另一个四格,使得ana不能再去占据它,这样ana一定只能占据所有四格数的一半,ana的面积就能确定

n,m中有奇数时,先按偶数考虑,多出来的部分显然不能由ana占据。。。

【代码】

RunID

User

Problem

Result

Memory

Time

Language

Length

Submit Time

2477856

zhyfzy

J

Accepted

0 KB

19 ms

C++ 4.8.2

442 B

2014-07-23 20:10:55


#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;
int i,j,k,n,T,nn,mm,ana,bob,K,m,sum;
int main()
{
	scanf("%d",&T);
	for (K=1;K<=T;K++)
	{
		scanf("%d%d",&n,&m);
		if (n%2) nn=n-1; else nn=n;
		if (m%2) mm=m-1; else mm=m;
		sum=nn*mm/4;//统计有多少个四格 
		ana=(sum+1)/2*4;//ana占所有的四格的一半,当四格数是奇数则除以二向上取整 
		bob=n*m-ana;
		printf("Case #%d: ",K);
		if (ana>bob) printf("Ana
");
		else
		if (ana<bob) printf("Bob
");
		else
		printf("Draw
");
	}
}


原文地址:https://www.cnblogs.com/zhyfzy/p/4021321.html