晚上只睡了三个小时的情况下做的这套题(考试的时候做一会儿睡一会儿),觉得题很简单,半小时敲完一二题,结果第三道题的深搜一直没有搜出来qwq。。。。最后还是写了30分的暴力算法。。。。心态巨崩无比(本来以为自己可以AK的)
T1神奇的幻方
我相信只要会写程序的人都会做这道题(话说近几年的大模拟的题真的不少啊)
#include<cstdio>
const int MAXN=45;
int f[MAXN][MAXN];
int main()
{
//freopen("magic.in","r",stdin);
//freopen("magic.out","w",stdout);
int n;
std::scanf("%d",&n);
int mid=(1+n)>>1;
f[1][mid]=1;
for(int i=2;i<=n*n;i++)
{
for(int j=1;j<=n;j++)
{
for(int k=1;k<=n;k++)
{
if(f[j][k]==i-1)
{
if(j==1&&k!=n)
{
f[n][k+1]=i;
}
if(k==n&&j!=1)
{
f[j-1][1]=i;
}
if(j==1&&k==n)
{
f[j+1][k]=i;
}
if(j!=1&&k!=n)
{
if(f[j-1][k+1]==0)
{
f[j-1][k+1]=i;
}
else
{
f[j+1][k]=i;
}
}
}
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
printf("%d ",f[i][j]);
}
printf("\n");
}
return 0;
}
T2 信息传递
画一下图就能知道这道题的目的就是让求一个DAG里面的最小环,由于题目保证有解,所以直接tarjan缩点虐之(值得一提的是这道题出题人貌似没有卡数据,如果在递归的时候所有点全部进栈的话应该是会卡爆的),当然,并查集或者直接线性扫描都能过这题,当做水题刷就好了
#include<cstdio>
#include<algorithm>
const int MAXN=2e5+5;
struct Edge
{
int nxt;
int to;
}edge[MAXN<<1];
int num;
int head[MAXN];
void add(int from,int to)
{
edge[++num].nxt=head[from];
edge[num].to=to;
head[from]=num;
}
int indx;
int color[MAXN];
int dgr[MAXN];
int dfn[MAXN];
int low[MAXN];
int stk[MAXN];
bool vis[MAXN];
int top;
int cnt;
void tarjan(int x)
{
indx++;
dfn[x]=low[x]=indx;
stk[++top]=x;
vis[x]=1;
for(int i=head[x];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(!dfn[v])
{
tarjan(v);
low[x]=std::min(low[x],low[v]);
}
else
if(vis[v])
{
low[x]=std::min(low[x],dfn[v]);
}
}
if(dfn[x]==low[x])
{
cnt++;
while(1)
{
int u=stk[top--];
vis[u]=0;
dgr[cnt]++;
color[u]=cnt;
if(u==x)
{
break;
}
}
}
}
int main()
{
//freopen("message.in","r",stdin);
//freopen("message.out","w",stdout);
int n;
std::scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int ti;
std::scanf("%d",&ti);
add(i,ti);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i])
{
tarjan(i);
}
}
int ans=0x7fffffff;
for(int i=1;i<=cnt;i++)
{
if(dgr[i]!=1&&dgr[i]<ans)
{
ans=dgr[i];
}
}
printf("%d\n",ans);
return 0;
}
T3 斗地主
究极大模拟。。。。据说剪枝以后的状压+dfs能过95分,不过正解是贪心+dfs暴搜,由于内存和时间都不算紧张,所以说最后的答案就完全靠细不细心了(然而样例2的答案一直少了1,最后发现就是单纯的没有加而已。。。)
#include<cstdio>
#include<cstring>
#include<algorithm>
int T,n;
int cnt[16];
int ans=23;
void dfs(int x)
{
if(x>ans)
{
return;
}
int s1;
int s2;
int s3;
int s4;
s1=s2=s3=s4=0;
for(int i=1;i<=14;i++)
{
if(cnt[i]==2)
{
s2++;
}
if(cnt[i]==1)
{
s1++;
}
}
for(int i=1;i<=14;i++)
{
if(cnt[i]==4)
{
s4++;
if(s1>=2)
{
s1-=2;
}
else if(s2>=2)
{
s2-=2;
}
else if(s2>=1)
{
s2--;
}
}
}
for(int i=1;i<=14;i++)
{
if(cnt[i]==3)
{
s3++;
if(s1>=1)
{
s1--;
}
else if(s2>=1)
{
s2--;
}
}
}
ans=std::min(ans,x+s1+s2+s3+s4);
int j;
for(int i=1;i<=8;i++)
{
for(j=i;j<=12;j++)
{
cnt[j]--;
if(cnt[j]<0)
{
break;
}
if(j-i>=4)
{
dfs(x+1);
}
}
if(j==13)
{
j--;
}
while(j>=i)cnt[j--]++;
}
for(int i=1;i<=10;i++)
{
for(j=i;j<=12;j++)
{
cnt[j]-=2;
if(cnt[j]<0) break;
if(j-i>=2)
{
dfs(x+1);
}
}
if(j==13)
{
j--;
}
while(j>=i) cnt[j--]+=2;
}
for(int i=1;i<=11;i++)
{
for(j=i;j<=12;j++)
{
cnt[j]-=3;
if(cnt[j]<0)
{
break;
}
if(j-i>=1)
{
dfs(x+1);
}
}
if(j==13)
{
j--;
}
while(j>=i)
{
cnt[j--]+=3;
}
}
}
int main()
{
//freopen("landlords.in","r",stdin);
//freopen("landlords.out","w",stdout);
int T,n;
std::scanf("%d%d",&T,&n);
while(T--)
{
std::memset(cnt,0,sizeof(cnt));
ans=23;
for(int i=1;i<=n;i++)
{
int x,y;
std::scanf("%d%d",&x,&y);
if(x==0)
{
cnt[14]++;
}
else
if(x==1)
{
cnt[12]++;
}
else
if(x==2)
{
cnt[13]++;
}
if(x>=3)
{
cnt[x-2]++;
}
}
dfs(0);
printf("%d\n",ans);
}
return 0;
}
/*
1 8
7 4
8 4
9 1
10 4
11 1
5 1
1 4
1 1
1 17
12 3
4 3
2 3
5 4
10 2
3 3
12 2
0 1
1 3
10 1
6 2
12 1
11 3
5 2
12 4
2 2
7 2
*/