冬令营Day2

冬令营第二天,终于摆托了爆零的命运。

下有隐藏代码和题目,闲人尽看

这天上午我们学了广搜和搜索优化。

 

int m,n;
char a[100][100];
int aa[100][100];
void DFS(int x,int y)
{
    if(x>=0&&y>=0&&x<m&&y<n)
    {
        if(a[x][y]=='.'&&!aa[x][y])
        {
            aa[x][y]=1;
            DFS(x,y-1);
            DFS(x,y+1);
            DFS(x+1,y);
            DFS(x-1,y);
        }
    }
}
int main()
{
    int x,y,k,q,i,j;
    while(scanf("%d%d",&n,&m)!=EOF,m||n)
    {
        k=0;
        memset(aa,0,sizeof(aa));
        getchar();
        for(x=0; x<m; x++){
            for(y=0; y<n; y++)
            {
                scanf("%c",&a[x][y]);
                if(a[x][y]=='@')
                {
                    i=x;
                    j=y;
                }
            }
            getchar();
        }
        a[i][j]='.';
        DFS(i,j);
        int sum=0;
        for(x=0; x<m; x++) for(y=0; y<n; y++)  sum+=aa[x][y];
        printf("%d\n",sum);
    } m,n;
char a[100][100];
int aa[100][100];
void DFS(int x,int y)
{
    if(x>=0&&y>=0&&x<m&&y<n)
    {
        if(a[x][y]=='.'&&!aa[x][y])
        {
            aa[x][y]=1;
            DFS(x,y-1);
            DFS(x,y+1);
            DFS(x+1,y);
            DFS(x-1,y);
        }
    }
}
int main()
{
    int x,y,k,q,i,j;
    while(scanf("%d%d",&n,&m)!=EOF,m||n)
    {
        k=0;
        memset(aa,0,sizeof(aa));
        getchar();
        for(x=0; x<m; x++){
            for(y=0; y<n; y++)
            {
                scanf("%c",&a[x][y]);
                if(a[x][y]=='@')
                {
                    i=x;
                    j=y;
                }
            }
            getchar();
        }
        a[i][j]='.';
        DFS(i,j);
        int sum=0;
        for(x=0; x<m; x++) for(y=0; y<n; y++)  sum+=aa[x][y];
        printf("%d\n",sum);
    }

下午:

 

1:造回文数:

只许看输入的是不是只有基数个单数

#include<bits/stdc++.h>
using namespace std;
int main()
{
freopen("palindromic.in","r",stdin);
freopen("palindromic.out","w",stdout);
int n,a,t=0;
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%d",&a);
t+=a%2;
}
puts(t<=1 ? "YES" : "NO");
fclose(stdin);
fclose(stdout);
}

2:找矩阵,一样中切

#include<bits/stdc++.h>
using namespace std;
const int N=522, M=N*N*2;
//char hexdigit[17]="0123456789ABCDEF";
int n,qx[M]={},qy[M]={},l[M]={},head=0,tail=0;
int a[N][N]={},s[N][N]={},len=0;
char ch[M]={};
int main()
{
freopen("coding.in","r",stdin);
freopen("coding.out","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
scanf("%d",&a[i][j]);
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
len=0;
head=tail=0;
++tail;
qx[tail]=1,qy[tail]=1,l[tail]=n;
while(head!=tail)
{
++head;
int sx=qx[head], sy=qy[head], sl=l[head];
int sum=s[sx+sl-1][sy+sl-1]-s[sx+sl-1][sy-1]
-s[sx-1][sy+sl-1]+s[sx-1][sy-1];
if(sum==sl*sl)
{
ch[++len]='0';
ch[++len]='1';
continue;
}
if(sum==0)
{
ch[++len]='0';
ch[++len]='0';
continue;
}
ch[++len]='1';
int nl=sl/2;
++tail;
qx[tail]=sx,qy[tail]=sy,l[tail]=nl;
++tail;
qx[tail]=sx,qy[tail]=sy+nl,l[tail]=nl;
++tail;
qx[tail]=sx+nl,qy[tail]=sy,l[tail]=nl;
++tail;
qx[tail]=sx+nl,qy[tail]=sy+nl,l[tail]=nl;
}
ch[++len]=0;
puts(ch+1);
}
fclose(stdin);
fclose(stdout);
return 0;
}//这题要用到广搜了;

3:把没有染色的染色,使水天一色染色的方案

#include<bits/stdc++.h>
using namespace std;
const int K=12;
const int mod=1000000007;
int n,m,k,a[K][K]={},now[K][K]={},oc[K][K]={};
int tryy(int x,int y,int c)
{
if(x>n)
return 1;
now[x][y]=now[x-1][y]|now[x][y-1];
if(a[x][y])
{
if(now[x][y]&oc[x][y])
return 0;
now[x][y]|=1<<a[x][y];
return y==m ? tryy(x+1,1,c) : tryy(x,y+1,c);
}
else
{
int s=0;
for(int i=1;i<=c;++i)
{
if((now[x][y]|oc[x][y])&(1<<i))
continue;
now[x][y]^=1<<i;
(s+=(y==m ? tryy(x+1,1,c) : tryy(x,y+1,c)))%=mod;
now[x][y]^=1<<i;
}
if(c<k)
{
now[x][y]^=1<<(c+1);
(s+=(k-c)*1ll*(y==m ? tryy(x+1,1,c+1) : tryy(x,y+1,c+1))%mod)%=mod;
now[x][y]^=1<<(c+1);
}
return s;
}
}
int main()
{
freopen("color.in","r",stdin);
freopen("color.out","w",stdout);
int T=1;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&k);
if(n+m-1>k)
{
puts("0");
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
scanf("%*d");
}
else
{
int c[K]={},totc=0; 
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
{
scanf("%d",&a[i][j]);
if(a[i][j])
{
if(c[a[i][j]]==0)
c[a[i][j]]=++totc;
a[i][j]=c[a[i][j]];
}
}
bool flag=false;
for(int i=n;i>=1;--i)
for(int j=m;j>=1;--j)
{
oc[i][j]=oc[i+1][j]|oc[i][j+1];
if(a[i][j])
{
if(oc[i][j]&(1<<a[i][j]))
flag=true;
oc[i][j]|=1<<a[i][j];
}
}
if(flag)
puts("0");
else
printf("%d\n",tryy(1,1,totc));
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
now[i][j]=oc[i][j]=0;
}
}
fclose(stdin);
fclose(stdout);
}

4:神经病一样的题目,救唐僧

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int N=110,Inf=1<<30,S=32;
const int x_[4]={0,1,0,-1}, y_[4]={1,0,-1,0};
struct state
{
int x,y,key,kill;
};
char ch[N][N]={};
int n,m,dis[N][N][10][32],num[N][N]={},tots=0,totkey=0;
void init()
{
tots=0;
totkey=m;
for(int i=1;i<=n;++i)
{
scanf("\n%s",ch[i]+1);
for(int j=1;j<=n;++j)
{
if(ch[i][j]=='S')
num[i][j]=tots++;
if(isdigit(ch[i][j]))
totkey=max(totkey,ch[i][j]-'0');
}
}
for(int i=0;i<=n+1;++i)
ch[i][0]=ch[0][i]=ch[n+1][i]=ch[i][n+1]='#';

for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
for(int k=0;k<=9;++k)
for(int s=(1<<tots)-1;s>=0;--s)
dis[i][j][k][s]=Inf;
}
void work()
{
queue<state> q;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if(ch[i][j]=='K')
{
dis[i][j][0][0]=0;
q.push((state){i,j,0,0});
}
while(!q.empty())
{
state s=q.front();
int nowd=dis[s.x][s.y][s.key][s.kill]+1;
q.pop();
if(ch[s.x][s.y]=='S' && !(s.kill&(1<<num[s.x][s.y])))
{
int &dest=dis[s.x][s.y][s.key][s.kill|(1<<num[s.x][s.y])];
if(dest==Inf)
{
dest=nowd;
q.push((state){s.x,s.y,s.key,s.kill|(1<<num[s.x][s.y])});
}
}
else
for(int d=0;d<4;++d)
{
int nx=s.x+x_[d], ny=s.y+y_[d];
if(ch[nx][ny]=='#')
continue;
if(isdigit(ch[nx][ny]) && ch[nx][ny]-'0'==s.key+1)
{
int &dest=dis[nx][ny][s.key+1][s.kill];
if(dest==Inf)
{
dest=nowd;
q.push((state){nx,ny,s.key+1,s.kill});
}
}
else
{
int &dest=dis[nx][ny][s.key][s.kill];
if(dest==Inf)
{
dest=nowd;
q.push((state){nx,ny,s.key,s.kill});
}
}
}
}
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if(ch[i][j]=='T')
{
int ans=Inf;
for(int s=(1<<tots)-1; s>=0; --s)
ans=min(ans,dis[i][j][totkey][s]);
if(ans==Inf)
puts("impossible");
else
printf("%d\n",ans);
}
}
int main()
{
freopen("saving.in","r",stdin);
freopen("saving.out","w",stdout);
scanf("%d%d",&n,&m);
while(n || m)
{
init();
work();
scanf("%d%d",&n,&m);
}
fclose(stdin);
fclose(stdout);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值