您的位置:首页 > 大数据 > 人工智能

2013 Multi-University Training Contest 6

2013-08-09 15:14 375 查看
1001 Cut Pieces

我们没过的版刷题,可是看了标程后发现我们确实不会,而且最多的排布方式只限于一大一小,我们一开始YY的大的放中间,小的放两边根本是错误的,小数据可能还没什么错,大数据就会发现错误。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#define N 1000000007
using namespace std;
inline void RD(int &ret)
{
char c;
do
{
c=getchar();
}
while(c<'0'||c>'9');
ret=c-'0';
while((c=getchar())>='0'&&c<='9')
{
ret=ret*10+(c-'0');
}
}
inline void OT(int a)
{
if(a>=10)
{
OT(a/10);
}
putchar(a%10+'0');
}
long long a[1000001],b[1000001],p[1000001],q[1000001];
int main()
{
int n,i,t,j,l,r,m;
long long sum,ans;
RD(t);
while(t--)
{
scanf("%d",&n);
for(i=0;i<n;++i)
{
scanf("%I64d",&a[i]);
}
sort(a,a+n);
reverse(a,a+n);//从大到小排列
j=0;
for(i=1;i<n;i+=2)//将a的值一大一小开始赋值到b中
{
b[i]=a[j++];
}
//j=0;
for(i=0;i<n;i+=2)
{
b[i]=a[j++];
}
p[0]=q
=1;
for(i=0;i<n;++i)
{
p[i+1]=p[i]*b[i]%N;//构造数列从前乘到后的数
}
for(i=n;i>0;--i)
{
q[i-1]=q[i]*b[i-1]%N;//构造数列从后乘到前的数
}
sum=0;
for(i=0;i<n-1;++i)
{
l=i;
r=i+1;
if(b[l]>b[r])
{
m=l;
}
else
{
m=r;
}
sum=(sum+p[m]*q[m+1])%N;//标程上的方法,只去掉bm
}
ans=n*p
%N;
ans=(ans-sum+N)%N;//总数减去重复的
printf("%I64d\n",ans);
}
return 0;
}

1004 Integer Partition
这题是之前第五场Partition的扩展,当时只是了解了五角数定理,但没有深入探究,结果这题就是对原先的P(n)在做一次递推运算,只是每次加上或者减去的项为p(n-j*(3*j+-1)*k/2)。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#define N 1000000007
using namespace std;
inline void RD(int &ret)
{
char c;
do
{
c=getchar();
}
while(c<'0'||c>'9');
ret=c-'0';
while((c=getchar())>='0'&&c<='9')
{
ret=ret*10+(c-'0');
}
}
inline void OT(int a)
{
if(a>=10)
{
OT(a/10);
}
putchar(a%10+'0');
}
long long a[100005];
void f()//递推式
{
int i,j;
long long sum;
a[0]=1;
a[1]=1;
a[2]=2;
for(i=2; i<=100000; ++i)
{
sum=0;
for(j=1; (i-j*(3*j-1)/2)>=0||(i-j*(3*j+1)/2)>=0; j++)
{
if(j%2==1)
{
if((i-j*(3*j-1)/2)>=0)
{
sum=(sum+a[(i-j*(3*j-1)/2)])%N;//注意不能写+=,不然会产生溢出错误,(不管你是longlong还是int)
}
if((i-j*(3*j+1)/2)>=0)
{
sum=(sum+a[(i-j*(3*j+1)/2)])%N;
}
}
else
{
if((i-j*(3*j-1)/2)>=0)
{
sum=(sum-a[(i-j*(3*j-1)/2)]+N)%N;//防止负数
}
if((i-j*(3*j+1)/2)>=0)
{
sum=(sum-a[(i-j*(3*j+1)/2)]+N)%N;
}
}
}
a[i]=sum;
}
}
int main()
{
f();
int t,n,j,k;
long long sum;
RD(t);
while(t--)
{
scanf("%d%d",&n,&k);
sum=a
%N;
for(j=1; (n-j*(3*j-1)*k/2)>=0||(n-j*(3*j+1)*k/2)>=0; j++)//看过才知道只要乘就行,太悲剧了
{
if(j%2==0)
{
if((n-j*(3*j-1)*k/2)>=0)
{
sum=(sum+a[(n-j*(3*j-1)*k/2)])%N;
}
if((n-j*(3*j+1)*k/2)>=0)
{
sum=(sum+a[(n-j*(3*j+1)*k/2)])%N;
}
}
else
{
if((n-j*(3*j-1)*k/2)>=0)
{
sum=(sum-a[(n-j*(3*j-1)*k/2)]+N)%N;
}
if((n-j*(3*j+1)*k/2)>=0)
{
sum=(sum-a[(n-j*(3*j+1)*k/2)]+N)%N;
}
}
}
printf("%I64d\n",sum%N);
}
return 0;
}

1008 MU Puzzle
全场唯一出的水题。

由于三种操作的存在,2^n-6k=sum(‘I的总数(可由U转换成)’),所以当sum=1或sum%6=2或者4时都是可行的

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
inline void RD(int &ret)
{
char c;
do
{
c=getchar();
}
while(c<'0'||c>'9');
ret=c-'0';
while((c=getchar())>='0'&&c<='9')
{
ret=ret*10+(c-'0');
}
}
inline void OT(int a)
{
if(a>=10)
{
OT(a/10);
}
putchar(a%10+'0');
}
int main()
{
int t,i,l,f,sum;
char a[1000001];
RD(t);
while(t--)
{
scanf("%s",a);
l=strlen(a);
f=0;
if(a[0]!='M')
{
f=1;
}
sum=0;
for(i=1;i<l;++i)
{
if(a[i]=='I')
{
sum+=1;
}
else if(a[i]=='U')//将U的数量也转化为I的数量
{
sum+=3;
}
else
{
f=1;
}
}
if(sum%6!=2&&sum%6!=4&&sum!=1)
{
f=1;
}
if(f==1)
{
printf("No\n");
}
else
{
printf("Yes\n");
}
}
return 0;
}

1010 Triangulation

空间博弈,Dawson’s Kayles 问题,表示完全不知道,百度一下后也发现只有一篇外语论文有提到。

有兴趣的可以去玩一下这个:传送门

标程上打的表也看不懂,最后还是自己写的sg函数,由于标程上说了循环节是34,所以就开了1000的数组。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
inline void RD(int &ret)
{
char c;
do
{
c=getchar();
}
while(c<'0'||c>'9');
ret=c-'0';
while((c=getchar())>='0'&&c<='9')
{
ret=ret*10+(c-'0');
}
}
inline void OT(int a)
{
if(a>=10)
{
OT(a/10);
}
putchar(a%10+'0');
}
int sg[1005];
bool t[1005];
void f()
{
int i,j;
for(i=2;i<1000;++i)
{
fill(t,t+i-1,false);
for(j=0;j<=i-2;++j)
{
t[sg[j]^sg[i-2-j]]=true;
}
for(j=0;;++j)
{
if(!t[j])
{
sg[i]=j;
break;
}
}
}
}
int main()
{
f();
int t,i,n,x,sum;
RD(t);
while(t--)
{
RD(n);
sum=0;
for(i=0;i<n;++i)
{
RD(x);
if(x<=100)
{
sum^=sg[x];
}
else
{
sum^=sg[x%34+3*34];
}
}
if(sum==0)
{
printf("Dave\n");
}
else
{
printf("Carol\n");
}
}
return 0;
}

1011 Unshuffle

最坑的题啊,题意很好理解,还是special judge,但最后也没发现这居然是一道2-sat。。。建完图,最后一个简单的dfs就搞定了。。。无语啊

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
inline void RD(int &ret)
{
char c;
do
{
c=getchar();
}
while(c<'0'||c>'9');
ret=c-'0';
while((c=getchar())>='0'&&c<='9')
{
ret=ret*10+(c-'0');
}
}
inline void OT(int a)
{
if(a>=10)
{
OT(a/10);
}
putchar(a%10+'0');
}
int a[2001],v[2001],n;
bool dfs(int x,int y)
{
int i,j,f=0;
if(x>=n-2)
{
return 1;
}
for(i=x;i<n-1;++i)
{
if(v[i]==0)
{
v[i]=-1;
for(j=y;j<n;++j)
{
if(a[i]==a[j]&&v[j]==0)
{
v[j]=1;
if(dfs(i+1,j+1)==1)
{
return 1;
}
v[j]=0;
}
}
f=1;
v[i]=0;
break;
}
}
if(f==0)
{
return 1;
}
return 0;
}
int main()
{
int t,i;
RD(t);
while(t--)
{
memset(v,0,sizeof(v));
RD(n);
for(i=0;i<n;++i)
{
RD(a[i]);
}
dfs(0,1);
for(i=0;i<n;++i)
{
if(v[i]==-1)
{
OT(0);
}
else if(v[i]==1)
{
OT(1);
}
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  HDU 多校