0x29 总结与练习
搜索真的菜。。困扰了很久,上个星期天没休息好导致整个礼拜没有精神。。
大概完成得七七八八了吧。真是深切的体会到暴力出奇迹的疯狂啊。
3、虫食算 从末位开始枚举判断,通过加数可以推出和的字母代表的数。那么加一个剪枝,就是通过当前所知字母对应值判断是否合法。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; int n,cnt,a[],c[];bool bk,v[];
char ss[][];
bool check(int k)
{
for(int i=k-;i>=;i--)
{
if(a[ss[][i]-'A'+]!=-&&a[ss[][i]-'A'+]!=-)
{
int d=a[ss[][i]-'A'+]+a[ss[][i]-'A'+];
if(a[ss[][i]-'A'+]!=-)
{
int dd=a[ss[][i]-'A'+];
if(dd==d%n||dd==(d+)%n)continue;
return false;
}
}
}
return true;
}
void dfs(int k,int w)
{
if(bk==true)return ;
if(cnt==n||(k==&&c[k]==))
{
bk=true;
for(int i=;i<n;i++)printf("%d ",a[i]);
printf("%d\n",a[n]);
return ;
}
if(w==)
{
int x=ss[w][k]-'A'+;
int d=a[ss[][k]-'A'+]+a[ss[][k]-'A'+]+c[k]; if(a[x]==-)
{
if(v[d%n]==true)return ; a[x]=d%n;c[k-]=d/n;v[d%n]=true;cnt++;
if(check(k))dfs(k-,);
a[x]=-;c[k-]=;v[d%n]=false;cnt--;
}
else if(a[x]==d%n)
{
c[k-]=d/n;
dfs(k-,);
c[k-]=;
}
}
else
{
int x=ss[w][k]-'A'+;
if(a[x]==-)
{
for(int i=;i<n;i++)
{
if(v[i]==false)
{
a[x]=i;v[i]=true;cnt++;
if(check(k))dfs(k,w+);
a[x]=-;v[i]=false;cnt--;
}
}
}
else dfs(k,w+);
}
}
int main()
{
scanf("%d",&n);
for(int i=;i<;i++)scanf("%s",ss[i]+);
memset(a,-,sizeof(a));
memset(c,,sizeof(c));
memset(v,false,sizeof(v));
bk=false;cnt=;dfs(n,);
return ;
}
虫食算
4、Mayan游戏 直接枚举移动方案并模拟状态的转移,hash判重就OK了。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std; int n,cnt,len[],a[][];bool bk;
struct ansnode{int x,y,z;}as[]; bool del[][];
void change(int x,int y,int z)
{
if(len[x+z]>=y)swap(a[x+z][y],a[x][y]);
else
{
a[x+z][++len[x+z]]=a[x][y];
for(int i=y;i<=len[x];i++)swap(a[x][i],a[x][i+]);
a[x][len[x]]=;len[x]--;
}
memset(del,false,sizeof(del));
bool qwq=true;
while(qwq)
{
qwq=false;
for(int i=;i<=;i++)
for(int j=;j<=len[i];j++)
{
if(i<=)
{
if(a[i][j]==a[i+][j]&&a[i+][j]==a[i+][j])
{
del[i][j]=true, del[i+][j]=true, del[i+][j]=true;
qwq=true;
}
}
if(len[i]-j>=)
{
if(a[i][j]==a[i][j+]&&a[i][j+]==a[i][j+])
{
del[i][j]=true, del[i][j+]=true, del[i][j+]=true;
qwq=true;
}
}
}
for(int i=;i<=;i++)
{
int tp=;
for(int j=;j<=len[i];j++)
if(del[i][j]==false)a[i][++tp]=a[i][j];
else cnt--;
for(int j=tp+;j<=len[i];j++)a[i][j]=;
len[i]=tp;
}
memset(del,false,sizeof(del));
}
}
map<int,bool>mp;
bool myhash(int k)
{
int d=k;
for(int i=;i<=;i++)
{
for(int j=;j<=len[i];j++)d=d*+a[i][j];
d=d*;
}
if(mp[d]==true)return true;
else {mp[d]=true;return false;}
}
void dfs(int k)
{
if(bk==true)return ;
if(cnt==&&k==n+)
{
for(int i=;i<=n;i++)printf("%d %d %d\n",as[i].x-,as[i].y-,as[i].z);
bk=true;return ;
}
if(cnt==||k==n+)return ; int tlen[],t[][],tcnt;
tcnt=cnt;
memcpy(tlen,len,sizeof(tlen));
memcpy(t,a,sizeof(t));
for(int i=;i<=;i++)
{
for(int j=;j<=len[i];j++)
{
if(i!=)
{
change(i,j,);
as[k].x=i, as[k].y=j, as[k].z=;
if(!myhash(k))
dfs(k+);
as[k].x=, as[k].y=, as[k].z=; cnt=tcnt;
memcpy(len,tlen,sizeof(len));
memcpy(a,t,sizeof(a));
}
if(i!=)
{
change(i,j,-);
as[k].x=i, as[k].y=j, as[k].z=-;
if(!myhash(k))
dfs(k+);
as[k].x=, as[k].y=, as[k].z=; cnt=tcnt;
memcpy(len,tlen,sizeof(len));
memcpy(a,t,sizeof(a));
}
}
}
}
int main()
{
scanf("%d",&n);
memset(len,,sizeof(len));
for(int i=;i<=;i++)
{
while(scanf("%d",&a[i][++len[i]])!=EOF){if(a[i][len[i]]==)break;}
len[i]--;cnt+=len[i];
}
bk=false;dfs();
if(bk==false)printf("-1\n");
return ;
}
Mayan游戏
5、poj1167 (题意真星星的难理解)现在也学乖了啊,对于这种分组的题要么就是填满一组又一组要么就是一个个加,这里的话是用一个个加的(因为我一开始写的一组又一组TLE啦:)),可以暴力把所有分组方案求出,从多到少填,其中要判断因为前面选了导致现在不合法。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; int n,ans,ti[];
struct line{int st,jg,c;}l[];int len;
bool cmp(line l1,line l2){return l1.c>l2.c;} bool check(int t,int jg)
{
while(t<)
{
if(ti[t]==)return false;
t+=jg;
}
return true;
}
void dfs(int k,int sum,int last)
{
if(sum==){ans=min(ans,k);return ;}
for(int i=last;i<=len;i++)
{
if(k+sum/l[i].c>=ans)break;
if(check(l[i].st,l[i].jg))
{
for(int t=l[i].st;t<;t+=l[i].jg)ti[t]--;
dfs(k+,sum-l[i].c,i);
for(int t=l[i].st;t<;t+=l[i].jg)ti[t]++;
}
}
}
int main()
{
int x;
while(scanf("%d",&n)!=EOF)
{
memset(ti,,sizeof(ti));
for(int i=;i<=n;i++)
scanf("%d",&x),ti[x]++;
len=;
for(int st=;st<;st++)
for(int jg=st+;st+jg<;jg++)
if(check(st,jg))
{
len++;
l[len].st=st;
l[len].jg=jg;
l[len].c=(-st)/jg+;
}
sort(l+,l+len+,cmp); ans=;
dfs(,n,);
printf("%d\n",ans);
}
return ;
}
poj1167
6、poj3700 这里还是一个个填,有四种情况,开一个新的上升/下降区间,or加入一个以前的上升/下降区间,单论上升,假如可以加入以前的上升区间,根据贪心的思想肯定选比自己小而且最大的那个更新,更加关键的是无需尝试新开一个,这也是贪心等效性的思想。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; int n,ans,c[],slen[],s[][];
bool dfs(int k)
{
if(slen[]+slen[]>=ans+)return false;
if(k==n+)return true; int id,t;
id=-;
for(int i=;i<=slen[];i++)
{
if(s[][i]<c[k])
if(id==-||s[][i]>s[][id])id=i;
}
if(id!=-)
{
t=s[][id];s[][id]=c[k];
if(dfs(k+))return true;
s[][id]=t;
}
else
{
s[][++slen[]]=c[k];
if(dfs(k+))return true;
s[][slen[]--]=;
} id=-;
for(int i=;i<=slen[];i++)
{
if(s[][i]>c[k])
if(id==-||s[][i]<s[][id])id=i;
}
if(id!=-)
{
t=s[][id];s[][id]=c[k];
if(dfs(k+))return true;
s[][id]=t;
}
else
{
s[][++slen[]]=c[k];
if(dfs(k+))return true;
s[][slen[]--]=;
}
return false;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n==)break;
for(int i=;i<=n;i++)scanf("%d",&c[i]);
slen[]=slen[]=;
memset(s,,sizeof(s));
for(ans=;;ans++)
{
if(dfs())break;
}
printf("%d\n",ans);
} return ;
}
poj3700
7、8、放到练习是侮辱智商??
9、子串变换 这题跑的挺快啊0ms,我还以为我写的这么又丑又慢会被卡,强行双向bfs,用KMP找子串相等,直接暴力转移状态,然后hash一下判重就差不多了。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
typedef long long LL; char sc[][],ss[][][];
struct node
{
char sl[];LL d;
}list[][];char sp[],su[];
map<LL,int>d[]; int p[];
int KMP(int w,int k,int be)
{
p[]=;int j=,len=strlen(ss[w][k]+);
for(int i=;i<=len;i++)
{
while(j>&&ss[w][k][i]!=ss[w][k][j+])j=p[j];
if(ss[w][k][i]==ss[w][k][j+])j++;
p[i]=j;
}
j=;int splen=strlen(sp+);
for(int i=;i<=splen;i++)
{
while(j>&&sp[i]!=ss[w][k][j+])j=p[j];
if(sp[i]==ss[w][k][j+])j++;
if(j==len&&i-len+>be)return i-len+;
}
return -;
} map<LL,bool>mp[];
int myhash()
{
int sulen=strlen(su+);LL d=;
for(int i=;i<=sulen;i++)d=d*93LL+(LL(su[i]));
return d;
} int main()
{
scanf("%s",sc[]+);scanf("%s",sc[]+);
int n=;
while(scanf("%s",ss[][++n]+)!=EOF){scanf("%s",ss[][n]+);}
n--; int head[],tail[]; head[]=;tail[]=;
memcpy(list[][].sl,sc[],sizeof(list[][].sl));
memcpy(su,sc[],sizeof(su));
list[][].d=myhash();mp[][list[][].d]=true;
d[][list[][].d]=;
memset(su,,sizeof(su)); head[]=;tail[]=;
memcpy(list[][].sl,sc[],sizeof(list[][].sl));
memcpy(su,sc[],sizeof(su));
list[][].d=myhash();mp[][list[][].d]=true;
d[][list[][].d]=;
memset(su,,sizeof(su)); //--------------init---------------------- while(head[]<tail[]&&head[]<tail[])
{
memcpy(sp,list[][head[]].sl,sizeof(sp));int splen=strlen(sp+);
LL spd=list[][head[]].d;
if(mp[][spd]&mp[][spd]){printf("%d\n",d[][spd]+d[][spd]);return ;}
for(int i=;i<=n&&d[][spd]<=;i++)
{
int be=KMP(,i,);
while(be!=-)
{
int len0=strlen(ss[][i]+),len1=strlen(ss[][i]+);
if(splen-len0+len1>)break;
int sulen=;
for(int j=;j<be;j++)su[++sulen]=sp[j];
for(int j=;j<=len1;j++)su[++sulen]=ss[][i][j];
for(int j=be+len0;j<=splen;j++)su[++sulen]=sp[j]; LL sud=myhash();
if(!mp[][sud])
{
mp[][sud]=true;d[][sud]=d[][spd]+;
memcpy(list[][tail[]].sl,su,sizeof(list[][tail[]].sl));
list[][tail[]].d=sud;
tail[]++;
}
memset(su,,sizeof(su)); be=KMP(,i,be);
}
}
head[]++; memcpy(sp,list[][head[]].sl,sizeof(sp));splen=strlen(sp+);
spd=list[][head[]].d;
if(mp[][spd]&mp[][spd]){printf("%d\n",d[][spd]+d[][spd]);return ;}
for(int i=;i<=n&&d[][spd]<=;i++)
{
int be=KMP(,i,);
while(be!=-)
{
int len0=strlen(ss[][i]+),len1=strlen(ss[][i]+);
if(splen-len1+len0>)break;
int sulen=;
for(int j=;j<be;j++)su[++sulen]=sp[j];
for(int j=;j<=len0;j++)su[++sulen]=ss[][i][j];
for(int j=be+len1;j<=splen;j++)su[++sulen]=sp[j]; LL sud=myhash();
if(!mp[][sud])
{
mp[][sud]=true;d[][sud]=d[][spd]+;
memcpy(list[][tail[]].sl,su,sizeof(list[][tail[]].sl));
list[][tail[]].d=sud;
tail[]++;
}
memset(su,,sizeof(su)); be=KMP(,i,be);
}
}
head[]++;
}
printf("NO ANSWER!\n");
return ;
}
子串变换
10、poj2044 二进制表示状态,记录四个角落多久没降雨,判重即可。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int Bin[];
const int dx[]={,-,-,,,,,,};
const int dy[]={,,,-,-,,,,}; int n,u[];
bool v[][][][][][];
int point(int x,int y){return (x-)*+y;}
bool check(int k,int x,int y)
{
int zt=;
zt^=Bin[point(x,y)];
zt^=Bin[point(x+,y)];
zt^=Bin[point(x,y+)];
zt^=Bin[point(x+,y+)];
return (<x)&&(x<=)&&(<y)&&(y<=)&&(!(zt&u[k]));
}
int dfs(int k,int x,int y,int rain[])
{
if(k==n+)return ;
if(v[k][point(x,y)][rain[]][rain[]][rain[]][rain[]])return ;
v[k][point(x,y)][rain[]][rain[]][rain[]][rain[]]=true;
for(int i=;i<=;i++)
{
int tx=x+dx[i],ty=y+dy[i];
int train[];memcpy(train,rain,sizeof(train));
for(int j=;j<=;j++)train[j]++;
if(tx==&&ty==)train[]=;
if(tx==&&ty==)train[]=;
if(tx==&&ty==)train[]=;
if(tx==&&ty==)train[]=;
if(check(k,tx,ty)&&train[]<=&&train[]<=&&train[]<=&&train[]<=)
{
if(dfs(k+,tx,ty,train))return ;
}
if(k==)break;
}
return ;
} int main()
{
Bin[]=;for(int i=;i<=;i++)Bin[i]=Bin[i-]*;
while(scanf("%d",&n)!=EOF)
{
if(n==)break; for(int i=;i<=n;i++)
{
u[i]=;int x;
for(int j=;j<=;j++)
{
scanf("%d",&x);
if(x==)u[i]^=Bin[j];
}
}
memset(v,false,sizeof(v));
int rain[];memset(rain,,sizeof(rain));
printf("%d\n",dfs(,,,rain));
}
return ;
}
poj2044
11、留坑
12、poj1945 这题真的是很奇淫了,较小数不能超过100?gc控到50都没问题
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; struct node
{
int x,y,c;
}list[];int head,tail;
bool mp[][];
void insert(int x,int y,int c)
{
if(x>y)swap(x,y);
if(y>||x>||x<||mp[x][y])return ;
mp[x][y]=true; list[tail].x=x,list[tail].y=y,list[tail].c=c;
tail++;if(tail==)tail=;
} int main()
{
int k;
scanf("%d",&k);
head=,tail=;
list[head].x=,list[head].y=,list[head].c=;
mp[][]=true;
while(head!=tail)
{
int x=list[head].x,y=list[head].y,c=list[head].c;
if(x== k||y==k){printf("%d\n",c);break;}
insert(x,x+y,c+), insert(y,x+y,c+);
insert(y-x,y,c+), insert(y-x,x,c+);
insert(x*,y,c+), insert(x,y*,c+);
insert(x,x*,c+), insert(y,y*,c+);
head++;if(head==)head=;
}
return ;
}
poj1945
13、poj4007 迭代加深,暴力dfs+bfs找被覆盖的点,当时我满脑子的都是神之折纸的个游戏啊,怎么IDA*,我玩的时候看到步数比颜色少就重来,但是这个故意卡好像。。结果gc%了一发就是这么搞?真是。。。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int dx[]={-,,,};
const int dy[]={,-,,}; int n,cnt,a[][]; int xx[],yy[];bool v[][];
bool check(int x,int y,int c){return <x&&x<=n&&<y&&y<=n&&a[x][y]==c;}
int bfs(int c)
{
int head=,tail=,cg=;xx[]=,yy[]=;
memset(v,false,sizeof(v));v[][]=true;
while(head<tail)
{
int x=xx[head],y=yy[head];
for(int i=;i<=;i++)
{
int tx=x+dx[i],ty=y+dy[i];
if((check(tx,ty,c)||a[tx][ty]==-)&&v[tx][ty]==false)
{
if(a[tx][ty]!=-)cg++;
v[tx][ty]=true;a[tx][ty]=-;
xx[tail]=tx;yy[tail]=ty;
tail++;
}
}
head++;
}
return cg;
}
bool bb[];
int count()
{
memset(bb,false,sizeof(bb));
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(a[i][j]!=-)bb[a[i][j]]=true;
int c=;
for(int i=;i<=;i++)
if(bb[i]==true)c++;
return c;
}
int ans;
bool dfs(int k)
{
if(k+count()>ans)return false;
if(cnt==)return true; int t[][];
for(int c=;c<=;c++)
{
memcpy(t,a,sizeof(t));
int d=bfs(c);
if(d>)
{
cnt-=d;
if(dfs(k+))return true;
cnt+=d;
}
memcpy(a,t,sizeof(a));
}
return false;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n==)break;
cnt=n*n;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
scanf("%d",&a[i][j]);
int c=a[][];
cnt--;a[][]=-;
cnt-=bfs(c);
if(cnt==)printf("0\n");
else
{
for(ans=;;ans++)
{
if(dfs())break;
}
printf("%d\n",ans);
}
}
return ;
}
poj4007
0x29 总结与练习的更多相关文章
- SQLSERVER中NULL位图的作用
SQLSERVER中NULL位图的作用 首先感谢宋沄剑提供的文章和sqlskill网站:www.sqlskills.com,看下面文章之前请先看一下下面两篇文章 SQL Server误区30日谈-Da ...
- 常用ASCII CHR碼對照
因為開發需求,把對照表留下來一下. Chr(0) Null Chr(29) 分组符 Chr(38) & Chr(48) 0 Chr(8) 退格 Chr(30) 記錄分離符號 Chr(39) ‘ ...
- spi子系统之驱动SSD1306 OLED
spi子系统之驱动SSD1306 OLED 接触Linux之前,曾以为读源码可以更快的学习软件,于是前几个博客都是一边读源码一边添加注释,甚至精读到每一行代码,实际上效果并不理想,看过之后就忘记了.主 ...
- I2C子系统之驱动SSD1306 OLED
理解I2C设备驱动框架,主要围绕四个结构体去分析就容易了. struct i2c_algorithm:提供I2C协议的实现的操作,如:master_xfer实现数据收发的最基本方法. struct i ...
- 嵌入式Linux驱动学习之路(二十六)DM9000C网卡驱动程序
基于DM9000C的原厂代码修改dm9000c的驱动程序. 首先确认内存的基地址 iobase. 确定中断号码. 打开模块的初始化函数定义. 配置内存控制器的相应时序(结合DM9000C.C的手册). ...
- Sharp Memory LCD (ls013b7dh03)驱动
网上找不到什么靠谱的资料,甚至我调好了夏普原厂和代理商还来找我要demo, 哎,苦逼的码农. lcd_main.c #include "ls013b7dh03.h" #inclu ...
- GSM07.10协议中串口复用使用的校验算法
] = { 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B ...
- sha512散列(C语言)
/** * \file sha4.h * * \brief SHA-384 and SHA-512 cryptographic hash function * * Copyright (C) 2006 ...
- sha1散列(C语言)
/** * \file sha1.h * * \brief SHA-1 cryptographic hash function * * Copyright (C) 2006-2010, Brainsp ...
随机推荐
- MongoDB索引05-30学习笔记
MongoDB 索引 索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录. 这种扫描全集合的查询效率是非常低的,特别在处理大 ...
- 9.18[XJOI] NOIP训练36
***在休息了周末两天(好吧其实只有半天),又一次投入了学车的怀抱,重新窝在这个熟悉的机房 今日9.18(今天以后决定不写打卡了) 日常一日总结 一个昏昏欲睡的早晨 打了一套不知道是谁出的题目,空间限 ...
- React 16 服务端渲染的新特性
React 16 服务端渲染的新特性 React 16 中关于服务端渲染的新特性 快速介绍React 16 服务端渲染的新特性,包括数组.性能.流等 React 16 终于来了!
- MBR分区表格式 - 简明概述
目前硬盘主要有MBR和GPT分区两种格式,前者是Windows XP之前时代主流的分区格式,后者则是现在Windows 8之后主流的分区格式.(Windows 7需要通过一些手段能实现支持GPT,而W ...
- javascript中的构造函数和原型及原型链
纯属个人理解,有错误的地方希望大牛指出,以免误人子弟 1.构造函数: 构造函数的作用 : 初始化由new创建出来的对象 new 的作用: 创建对象(空对象) new 后面跟的是函数调用,使用ne ...
- Docker的特性解析
Docker简介与入门:http://segmentfault.com/blog/p_chou/1190000000448808 Docker是个新生的事物,概念类似虚拟化.网上关于Docker入门的 ...
- 生成式模型:LDA
原文链接:http://blog.sina.com.cn/s/blog_5033f3b40101flbj.html 文章图文并茂,我就不转载了!!! LSI-Laten ...
- 插入排序InsertSort
插入排序:从第二个数开始 一直和前面的数组比较 获得排序定位 代码 /** *插入排序 */ public class InsertSort { public static void inser ...
- day03深浅拷贝、文件操作和函数初识
一.赋值.浅拷贝与深拷贝 直接赋值:其实就是对象的引用(别名). 浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象. 深拷贝(deepcopy): copy 模块的 deepcopy 方法, ...
- python文件操作IO
模式 描述 r 以只读方式打开文件.文件的指针将会放在文件的开头.这是默认模式. rb 以二进制格式打开一个文件用于只读.文件指针将会放在文件的开头.这是默认模式.一般用于非文本文件如图片等. r+ ...