很水
#include <cstdio>
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m,a;
int ans1=0,ans2=0;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%d",&a);
ans1+=a;
}
for(int i=0;i<m;i++)
{
scanf("%d",&a);
ans2+=a;
}
if(ans1==ans2) printf("Draw\n");
else if(ans1>ans2) printf("Calem\n");
else printf("Serena\n");
}
return 0;
}
【ZOJ 3777 Problem Arrangement】
题意:假设在给定的n*n矩阵中选n个数字(假设选中的是p[ i ][ j ] 选中的n个书中i不一样,j也不一样)有ans中方法,求总方案数/ans 化为最简的
思路:
状压dp
dp[ i ][ j ] i表示状态 j表示所得的分数
<span style="font-size:14px;">#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
int p[20][20];
int dp[(1<<12)+5][1210];
int gcd(int a,int b)
{
int res=1;
while(res)
{
res=a%b;
a=b;
b=res;
}
return a;
}
int main()
{
int T,n,m;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&p[i][j]);
}
}
int ans=1;
for(int i=1;i<=n;i++) ans*=i;
int tot=1<<n;
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int s=0;s<tot;s++)
{
int cnt=0;
for(int i=0;i<n;i++)
{
if(s&(1<<i)) cnt++;
}
for(int j=0;j<n;j++)
{
if(s&(1<<j)) continue;
for(int ss=0;ss<=m;ss++)
{
dp[s|(1<<j)][min(m,ss+p[cnt+1][j+1])]+=dp[s][ss];
}
}
}
if(dp[tot-1][m]==0) printf("No solution\n");
else
{
int kk=gcd(ans,dp[tot-1][m]);
printf("%d/%d\n",ans/kk,dp[tot-1][m]/kk);
}
}
return 0;
}</span>
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m,p;
int ans=0,maxn=0;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%d",&p);
maxn=max(maxn,p);
ans+=p;
}
ans=ans/m+min(1,ans%m);
ans=max(ans,maxn);
printf("%d\n",ans);
}
return 0;
}
【ZOJ 3779 Chessboard and Flowers】
【ZOJ 3780 Paint the Grid Again】
【ZOJ 3781 Paint the Grid Reloaded】
搜索,一个连通块只能到相邻的的连通块,所以题目就转化为从一个连通块到离它最远的联通块的最少步数
<span style="font-size:14px;">#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <set>
#include <queue>
using namespace std;
char s[45][45];
set<int>Set[1610];
int tot,head[1610];
int vis[45][45],sz;
int f[4][2]={0,1,0,-1,1,0,-1,0};//这样写不会超时!!
struct edge
{
int to,nxt;
}e[(1610*4)<<1];
void add(int u,int v)
{
e[++tot].to=v;
e[tot].nxt=head[u];
head[u]=tot;
e[++tot].to=u;
e[tot].nxt=head[v];
head[v]=tot;
}
void dfs(int i,int j,char t)
{
int x,y;
for(int k=0;k<4;k++)
{
x=i+f[k][0];
y=j+f[k][1];
int u=sz,v=vis[x][y];
if(v && s[x][y]!=t && !Set[u].count(v))
{
Set[u].insert(v);
Set[v].insert(u);
add(u,v);
}
else if(!v && s[x][y]==t)
{
vis[x][y]=sz;
dfs(x,y,t);
}
}
}
int d[1610];
int bfs(int k)
{
int re=0;
queue<int>q;
int x,y;
memset(d,0,sizeof(d));
q.push(k);
d[k]=1;
while(!q.empty())
{
x=q.front();
q.pop();
for(int i=head[x];i;i=e[i].nxt)
{
y=e[i].to;
if(d[y]) continue;
q.push(y);
d[y]=d[x]+1;
re=max(re,d[y]-1);
}
}
return re;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%s",s[i]+1);
}
for(int i=0;i<=m+1;i++) s[0][i]=s[n+1][i]='#';
for(int i=0;i<n+1;i++) s[i][0]=s[i][m+1]='#';
sz=0;
memset(vis,0,sizeof(vis));
for(int i=0;i<1610;i++) Set[i].clear();
tot=0;
memset(head,0,sizeof(head));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(vis[i][j]) continue;
vis[i][j]=++sz;
dfs(i,j,s[i][j]);
}
}
int ans=sz;
for(int i=1;i<=sz;i++)
{
ans=min(ans,bfs(i));
}
printf("%d\n",ans);
}
return 0;
}</span>
【ZOJ 3782 Ternary Calculation】
【ZOJ 3785 What day is that day?】
就是求等比数列
<span style="font-size:14px;">#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
int a[10],q[10],k[10];
char str[7][10]={"Saturday","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday"};
int mul(int a,int li)
{
int s=1;
while(li)
{
if(li&1) s=(s*a)%7;
a=(a*a)%7;
li>>=1;
}
return s;
}
void init()
{
a[1]=1;
for(int i=2;i<=7;i++)
{
a[i]=mul(i,i);
q[i]=mul(i,7);
}
}
int main()
{
init();
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int ans=0;
if(n<=7)
{
for(int i=1;i<=n;i++)
{
ans=(ans+a[i])%7;
}
}
else
{
for(int i=1;i<=7;i++)
{
k[i]=n/7;
if(n%7>=i) k[i]++;
}
ans=k[1]%7;
for(int i=2;i<=7;i++)
{
int ss=a[i]*(mul(q[i],k[i])-1)*mul(q[i]-1,5)%7;
ans=(ans+ss)%7;
}
}
printf("%s\n",str[ans]);
}
return 0;
}</span>
【ZOJ 3786 Unreachable Statement】