day4
来源:互联网 发布:ubuntu 安装glsl 编辑:程序博客网 时间:2024/06/04 01:16
alien
飞船降落问题
矩阵前缀和+枚举
求出前缀和,暴力枚举每一个子矩阵的和,是0就可以降落
注意有正方形飞船,长度不等于点
#include<cstdio>#include<iostream>#include<cstring>using namespace std;#define D "%d"#define for(i,x,y) for(int i=x;i<=y;i++)#define prf printf#define scf scanfint n,m,r,c,ans;int a[1999][1999],s[1999][1999];int main(){ freopen("alien.in","r",stdin); freopen("alien.out","w",stdout); scf(D D D D,&n,&m,&r,&c); for(i,1,r) { int x,y; scf(D D,&x,&y); a[x][y]=1; } for(i,1,n) for(j,1,m) s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j]; for(k,1,c) { int x,y; ans=0; scf(D D,&x,&y); for(i,1,n) for(j,1,m) if(i+x-1<=n&&j+y-1<=m) { int w=s[i+x-1][j+y-1]-s[i-1][j+y-1]-s[i+x-1][j-1]+s[i-1][j-1]; if(w==0) ans++; } if(x!=y) { for(i,1,n) for(j,1,m) if(i+y-1<=n&&j+x-1<=m) { int w=s[i+y-1][j+x-1]-s[i-1][j+x-1]-s[i+y-1][j-1]+s[i-1][j-1]; if(w==0) ans++; } } prf(D "\n",ans); }}
game
博弈题
有n个点,m条边
两个人给点染色
得到点的权值和边的权值,求最优解的差(保证点偶数个)
直接均摊
他们都是最优解
所以不会看到另一个人得到最多的
所以一定会然一条边的另一边
最后排序减一下就行了
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;#define D "%d"#define for(i,x,y,z) for(int i=x;i<=y;i+=z)#define prf printf#define scf scanfint n,m;double w[19199],ans;int main(){ freopen(".in","r",stdin); freopen(".out","w",stdout); scf(D D,&n,&m); for(i,1,n,1) scf("%lf",&w[i]); for(i,1,m,1) { int x,y; double z; scf(D D "%lf",&x,&y,&z); w[x]+=z/2.0; w[y]+=z/2.0; } sort(w+1,w+n+1); for(i,1,n,2) ans+=w[i+1]-w[i]; prf(D,int (ans));}
fortress
大爆搜
没有什么技巧
就是一个超级大爆搜花了我两小时才调完
先打个表,将读入的问题搞好
再用邻接表弄,没墙就连上边
dfs搜有多少房间,搜最大的就先那种染色题一样
然后再删边添边,一次一次爆搜,找最大的
#include<cstdio>#include<cstring>#include<iostream>using namespace std;int a[99][99],c[2600][2699],f[9999],ans,m,n,x,y;char z;int nex[99999],head[9999],to[9999],tot,max1;int up(int x,int y){ to[tot]=0; c[y][x]=0; head[y]=nex[tot]; nex[tot]=0; tot--; to[tot]=0; c[x][y]=0; head[x]=nex[tot]; nex[tot]=0; tot--;}int add(int x,int y){ tot++; to[tot]=y; c[x][y]=1; nex[tot]=head[x]; head[x]=tot; tot++; to[tot]=x; c[y][x]=1; nex[tot]=head[y]; head[y]=tot;}int dfs(int x){ for(int i=head[x];i;i=nex[i]) { int tmp=to[i]; if(!f[tmp]) { ans++; f[tmp]=1; dfs(tmp); } }}int cnt;int b[16][5]={ 4,1,2,4,8, 3,2,4,8,0, 3,1,4,8,0, 2,4,8,0,0, 3,1,2,8,0, 2,2,8,0,0, 2,1,8,0,0, 1,8,0,0,0, 3,1,2,4,0, 2,2,4,0,0, 2,1,4,0,0, 1,4,0,0,0, 2,1,2,0,0, 1,2,0,0,0, 1,1,0,0,0, 0,0,0,0,0,};int main(){ freopen("fortress.in","r",stdin); freopen("fortress.out","w",stdout); scanf("%d%d",&m,&n);int t=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { ++t; a[i][j]=t; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { int x; scanf("%d",&x); for(int k=1;k<=b[x][0];k++) { if(b[x][k]==2&&i-1>=1) add(a[i][j],a[i-1][j]); if(b[x][k]==1&&j-1>=1) add(a[i][j],a[i][j-1]); if(b[x][k]==8&&i+1<=n) add(a[i][j],a[i+1][j]); if(b[x][k]==4&&j+1<=m) add(a[i][j],a[i][j+1]); } } for(int i=1;i<=t;i++) if(!f[i]) f[i]=1,cnt++,ans=1,dfs(i),max1=max(ans,max1); printf("%d\n%d\n",cnt,max1);max1=0; for(int j=1;j<=m;j++) for(int i=n;i>=1;i--) { memset(f,0,sizeof(f)); if(!c[a[i][j]][a[i-1][j]]&&i-1>=1) { add(a[i][j],a[i-1][j]); for(int k=1;k<=n;k++) for(int q=1;q<=m;q++) { ans=0; dfs(a[i][j]); if(max1<ans) { max1=ans; x=i,y=j,z='N'; } } up(a[i][j],a[i-1][j]); } memset(f,0,sizeof(f)); if(!c[a[i][j]][a[i][j+1]]&&j+1<=m) { add(a[i][j],a[i][j+1]); for(int k=1;k<=n;k++) for(int q=1;q<=m;q++) { ans=0; dfs(a[i][j]); if(max1<ans) { max1=ans; x=i,y=j,z='E'; } } up(a[i][j],a[i][j+1]); } } printf("%d\n%d %d %c",max1,x,y,z);}
阅读全文
1 0