1、栅栏迷宫

田野上搭建了一个黄金大神专用的栅栏围成的迷宫。幸运的是,在迷宫的边界上留出了两段栅栏作为迷宫的出口。更幸运的是,所建造的迷宫是一个“完美的”迷宫:即你能从迷宫中的任意一点找到一条走出迷宫的路。给定迷宫的宽W(1<=W<=38)及长H(1<=H<=100)。 2*H+1行,每行2*W+1的字符以下面给出的格式表示一个迷宫。然后计算从迷宫中最“糟糕”的那一个点走出迷宫所需的步数(就是从最“糟糕”的一点,走出迷宫的最少步数)。(即使从这一点以最优的方式走向最靠近的出口,它仍然需要最多的步数)当然了,黄金大神让你必须只会水平或垂直地在X或Y轴上移动,你不能从来不走对角线。每移动到一个新的方格算作一步(包括移出迷宫的那一步)这是一个W=5,H=3的迷宫:

+-+-+-+-+-+

|         |

+-+ +-+ + +

|     | | |

+ +-+-+ + +

| |     |

+-+ +-+-+-+

如上图的例子,栅栏的柱子只出现在奇数行或奇数列。每个迷宫只有两个出口。

PROGRAM NAME: maze

INPUT FORMAT:

(file maze.in)

第一行: W和H(用空格隔开)

第二行至第2*H+1行:  每行2*W+1个字符表示迷宫

OUTPUT FORMAT:

(file maze.out)

输出一个单独的整数,表示能保证牛从迷宫中任意一点走出迷宫的最小步数。

SAMPLE INPUT

5 3

+-+-+-+-+-+

|         |

+-+ +-+ + +

|     | | |

+ +-+-+ + +

| |     |

+-+ +-+-+-+

SAMPLE OUTPUT

9

Bfs(妈的把判重放到出队的时候就炸了....)

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 310
using namespace std;
int n,m,head=,tail,f[maxn][maxn];
char s[maxn][maxn],c;
struct node{
int x,y,t;
}q[maxn*maxn];
int xx[]={,,,-};
int yy[]={,-,,};
int Bfs(){
int mx=;
while(head<=tail){
node p=q[head++];
int x=p.x,y=p.y,t=p.t;
mx=max(mx,t);
for(int i=;i<;i++){
int nx=x+xx[i];
int ny=y+yy[i];
if(nx>&&nx<=n&&ny>&&ny<=m&&f[nx][ny]==&&s[nx][ny]==' ')
f[nx][ny]=,q[++tail]=(node){nx,ny,t+};
}
}
return mx;
}
int main()
{
freopen("maze.in","r",stdin);
freopen("maze.out","w",stdout);
scanf("%d%d",&m,&n);c=getchar();
m=m*+;n=n*+;
for(int i=;i<=n;i++)gets(s[i]+);
for(int i=;i<=m;i++)
if(s[][i]==' ')q[++tail]=(node){,i,},f[][i]=;
for(int i=;i<=m;i++)
if(s[n][i]==' ')q[++tail]=(node){n,i,},f[n][i]=;
for(int i=;i<=n;i++)
if(s[i][]==' ')q[++tail]=(node){i,,},f[i][]=;
for(int i=;i<=n;i++)
if(s[i][m]==' ')q[++tail]=(node){i,m,},f[i][m]=;
printf("%d\n",Bfs()+>>);
return ;
}

2、人偶师(alice.cpp/c/pas)

【题目描述】

n点m双向边的图,每个点有2个状态:开和关。每次操作改变一个点的状态,以及与其有边直接相连的点的状态。问开启所有点至少需要多少次操作。

【输入格式】

第一行2个整数n,m。

第二行n个整数,第i个数表示第i点的状态,0为关,1为开。

第3..m+2行,每行2个整数a,b,表示a和b直接相连,同一条边不会出现多次。

【输出格式】

第一行一个整数k表示最少的操作次数,所有数据保证至少有一组可行解。

第二行k个整数,表示操作的点的编号。

【样例输入】

4 3

1 1 0 0

2 3

1 3

2 4

【样例输出】

3

1 2 3

【数据范围】

对于30%的数据,1<=n<=10,0<=m<=40

对于60%的数据,1<=n<=30,0<=m<=100

对于100%的数据,1<=n<=40,0<=m<=500

暴力+剪枝70

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,m,num,head[],c[],s[],r[],f[],sum=,cr[];
struct node{
int v,pre;
}e[];
void Add(int from,int to){
num++;e[num].v=to;
e[num].pre=head[from];
head[from]=num;
}
void Dfs(int now){
int S=;
for(int i=;i<=n;i++)
if(f[i])S++;
if(S>=sum)return;
if(now==n+){
int flag=;
for(int i=;i<=n;i++)
if(!r[i]){
flag=;break;
}
if(flag==){
int cnt=;
for(int i=;i<=n;i++)
if(f[i])cnt++;
if(cnt<sum){
sum=cnt;cr[]=;
for(int i=;i<=n;i++)
if(f[i])cr[++cr[]]=i;
}
}
return;
}
for(int i=;i<=n;i++)
if(c[i]==s[i]&&r[i]==)return;
c[now]++;
for(int i=head[now];i;i=e[i].pre)
c[e[i].v]++;
Dfs(now+);
for(int i=head[now];i;i=e[i].pre)
c[e[i].v]--;
r[now]=!r[now];f[now]=;
for(int i=head[now];i;i=e[i].pre)
c[e[i].v]++,r[e[i].v]=!r[e[i].v];
Dfs(now+);
for(int i=head[now];i;i=e[i].pre)
c[e[i].v]--,r[e[i].v]=!r[e[i].v];
c[now]--;r[now]=!r[now];f[now]=;
}
int main()
{
freopen("alice.in","r",stdin);
freopen("alice.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d",&r[i]);s[i]++;
}
int u,v;
for(int i=;i<=m;i++){
scanf("%d%d",&u,&v);
Add(u,v);Add(v,u);
s[u]++;s[v]++;
}
Dfs();
printf("%d\n",sum);
for(int i=;i<=cr[];i++)
printf("%d ",cr[i]);
return ;
}

正解分两段暴力+hash

/*
map会T两个点...
改成hash 似乎还不对 但cena测试过了....
分两块Dfs 前半段记录信息A
代表改成某个状态是的按下灯的方案
这里用longlong存储的
后半段结束的时候 now^end代表的是对应前半段的状态
这时候在用刚才存下的查一下 取小
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#define ll long long
#define mod 2333333
using namespace std;
ll n,m,a[],p[],Mi[],end,N,falg,mx=,ans;
ll num,head[mod+];
struct node{
ll v1,v2,pre;
}e[mod*];
//map<ll,ll>A;//每个灯这个状态时 按的状态
ll Cal(ll x)
{
ll sum=;
for(int i=;i<=n;i++)
if(Mi[i]&x)sum++;
return sum;
}
void Insert(ll now,ll used){
ll ha=(now++now**)%mod;
num++;e[num].v1=now;e[num].v2=used;
e[num].pre=head[ha];head[ha]=num;
}
ll Find(ll now){
ll ha=(now++now**)%mod;
for(int i=head[ha];i;i=e[i].pre)
if(e[i].v1==now)return e[i].v2;
return ;
}
void Dfs(ll x,ll now,ll used){//第几个开关 每个灯亮不亮的状态 每个灯按不按的状态
if(x==N+){
if(now==end){
if(Cal(used)<mx){
mx=Cal(used);ans=now;
}
}
if(!falg){
ll t=Find(now);
//A[now];
if(!t)Insert(now,used);
//A[now]=used;
else if(Cal(t)>Cal(used))Insert(now,used);
//A[now]=used;
}
else{
ll t=Find(now^end);
//A[now^end];//从now按到目标状态的差 按出来 每个灯按不按的状态
if(!t)return;
ll sum=Cal(t)+Cal(used);
if(sum<mx){
mx=sum;ans=t+used;
}
}
return ;
}
Dfs(x+,now,used);
Dfs(x+,now^p[x],used+Mi[x]);//按下了x
}
int main()
{
//freopen("alice.in","r",stdin);
//freopen("alice.out","w",stdout);
scanf("%d%d",&n,&m);
Mi[]=;
for(int i=;i<=;i++)
Mi[i]=Mi[i-]<<;
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
if(!a[i])end+=Mi[i];
}
int u,v;
for(int i=;i<=m;i++){
scanf("%d%d",&u,&v);
p[u]|=Mi[v];p[v]|=Mi[u];//按下这个灯 有那几个会变
}
for(int i=;i<=n;i++)
p[i]|=Mi[i];
N=n/;Dfs(,,);
falg=;N=n;Dfs(n/+,,);
printf("%d\n",mx);
for(int i=;i<=n;i++)
if(Mi[i]&ans)printf("%d ",i);
return ;
}

3、交通(traffic.c/cpp/pas)

黄金大神国的首都位于hzwer河中的一座岛屿。一道上班的时候,成千上万辆汽车通过岛屿从西岸的住宅区(由桥连接岛的西部)到东岸的工业区(由桥连接岛的东部)。
    该岛类似于矩形,它的边平行于主方向。故可将它看作是笛卡尔坐标系中的一个A*B的矩形,它的对角分别为(0, 0)和(A, B)。
    岛上有n个交通节点(后宫建筑),编号为1…n,第i个节点坐标为(xi, yi)。如果一个节点的坐标为(0, y),它就位于岛的西岸。类似的,坐标为(A, y)的节点位于岛的东岸。各个节点由街道连接,每条街道用线段连接两个节点。街道有单向行驶或双向行驶之分。除端点外任意两条街道都没有公共点。也没有桥梁或者隧道。
    你不能对道路网络形状做任何其他假设。沿河岸的街道或节点可能没有入口或者出口街道。由于交通堵塞日趋严重,黄金大神想快速治理好他的国家,于是聘请你测试岛上当前的道路网是否足够。要求你写一个程序确定从岛的西岸的每个节点能够到达东岸的多少个节点。

【输入格式】

第1行包含4个整数n, m, A, B,分别表示hzwer市中心的节点数,街道数和岛屿的尺寸。
    接下来的n行,每行包含两个整数xi,yi (0≤xi≤A,0≤yi≤B),表示第i个节点的坐标。任意两个节点的坐标都不相同。
再往下的m行表示街道,每条街道用3个整数ci, di, ki(1≤ci, di≤n, ci≠di, ki∈{1,2}),表示节点ci、di有街道连接,如果ki=1,表示从ci到di的街道是单向的,否则,这条街道可以双向行驶。每个无序对{ci, di}最多出现1次。
    你可以假设西岸节点中至少有1个能够到达东岸的一些节点。

【输出格式】

为每个西岸节点输出1行,表示这个节点出发能够到达东岸的节点数目

【样例输入】

12 13 7 9

0 1

0 3

2 2

5 2

7 1

7 4

7 6

7 7

3 5

0 5

0 9

3 9

1 3 2

3 2 1

3 4 1

4 5 1

5 6 1

9 3 1

9 4 1

9 7 1

9 12 2

10 9 1

11 12 1

12 8 1

12 10 1

【样例输出】

4

4

0

2

【数据范围】

对于30%的数据,n, m≤6000

对于100%的数据,1≤n≤300000, 0≤m≤900000,1≤A,B≤10^9

暴力dfs

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 300010
using namespace std;
int n,m,A,B,num,head[maxn],f[maxn],p[maxn],tot,sum;
struct P{
int o,Y,cnt;
}Xi[maxn];
struct node{
int v,pre;
}e[maxn**];
int init(){
int x=;char s=getchar();
while(s<''||s>'')s=getchar();
while(s>=''&&s<=''){x=x*+s-'';s=getchar();}
return x;
}
int cmp(const P &a,const P &b){
return a.Y>b.Y;
}
void Add(int from,int to){
num++;e[num].v=to;
e[num].pre=head[from];
head[from]=num;
}
void Dfs(int now){
if(p[now]==)sum++;
for(int i=head[now];i;i=e[i].pre){
int v=e[i].v;
if(f[v])continue;
f[v]=;Dfs(v);
}
}
int main()
{
freopen("traffic.in","r",stdin);
freopen("traffic.out","w",stdout);
n=init();m=init();A=init();B=init();
int x,y,z;
for(int i=;i<=n;i++){
x=init();y=init();
if(x==)Xi[++tot]=(P){i,y,};
else if(x==A)p[i]=;
}
for(int i=;i<=m;i++){
x=init();y=init();z=init();
Add(x,y);if(z==)Add(y,x);
}
for(int i=;i<=tot;i++){
memset(f,,sizeof(f));
sum=;f[Xi[i].o]=;
Dfs(Xi[i].o);
Xi[i].cnt=sum;
}
sort(Xi+,Xi++tot,cmp);
for(int i=;i<=tot;i++)
printf("%d\n",Xi[i].cnt);
return ;
}

9.28noip模拟试题的更多相关文章

  1. 9.28NOIP模拟题

    9.28NOIP模拟题 题目 哈 哈哈 哈哈哈 英文题目与子目录名 ha haha hahaha 单个测试点时间限制 1秒 1秒 1秒 内存限制 256M 128M 64M 测试点数目 10 10 1 ...

  2. 模拟试题C

    模拟试题C 一.单项选择题(2′*14 =28′) 1.双线性法向插值法(Phong Shading)的优点是( ) A)法向计算精确 B)高光域准确 C)对光源和视点没有限制 D)速度较快 2.用编 ...

  3. 模拟试题B

    模拟试题B 一.单项选择题(2′*8 =16′) 1.灰度等级为256级,分辨率为2048*1024的显示器,至少需要的帧缓存容量为( ) A)512KB B)1MB C)2MB D)3MB 2.在多 ...

  4. 模拟试题A

    模拟试题A 一.单项选择题(2′*12=24′) 1.下面各种坐标变换中,会产生变换前后维度的改变的是( ) A)建模变换 B)观察变换 C)投影变换 D)视口变换 2.下列描述深度缓冲消隐算法的特点 ...

  5. CCF 模拟试题——出现次数最多的数 官方答案解析及自己写的正确答案

    前几天知道的CCF计算机职业资格认证考试,觉得好像比软考含金量高一些,就去了解了一下,做了模拟试题中的 “出现次数最多的数” 这道题,我的算法和官方答案算法不同,个人觉得觉得官方的好一点,没那么繁琐, ...

  6. 11.9 noip模拟试题

    NOIP2016 模拟赛——那些年,我们学过的文化课背单词(word.c/cpp/pas)[题目描述]fqk 退役后开始补习文化课啦, 于是他打开了英语必修一开始背单词. 看着满篇的单词非常头疼, 而 ...

  7. 10.26 noip模拟试题

    enc[问题背景]zhx 和他的妹子聊天.[问题描述]考虑一种简单的加密算法.假定所有句子都由小写英文字母构成,对于每一个字母,我们将它唯一地映射到另一个字母.例如考虑映射规则:a->b, b- ...

  8. 9.29noip模拟试题

    环上的游戏(cycle) 有一个取数的游戏.初始时,给出一个环,环上的每条边上都有一个非负整数.这些整数中至少有一个0.然后,将一枚硬币放在环上的一个节点上.两个玩家就是以这个放硬币的节点为起点开始这 ...

  9. 9.20 noip模拟试题

      Problem 1 双色球(ball.cpp/c/pas) [题目描述] 机房来了新一届的学弟学妹,邪恶的chenzeyu97发现一位学弟与他同名,于是他当起了善良的学长233 “来来来,学弟,我 ...

随机推荐

  1. vbox里面的Ubuntu虚拟机与主机win7之间设置共享文件夹

    有时候我们希望虚拟机和主机之间进行通信,例如传一些文件.那么设置共享文件夹就是一种很好的方式. 这里我的主机是win7系统,vbox里面的虚拟机是Ubuntu. 1.首先安装vbox的VBOXGues ...

  2. andorid studio

    http://www.cnblogs.com/smyhvae/p/4390905.html

  3. 转-[Python 学习]2.5版yield之学习心得

    在 shhgs 发布了关于< Py 2.5 what’s new 之 yield>之后,原来我不是特别关注 yield 的用法,因为对于2.3中加入的yield相对来说功能简单,它是作为一 ...

  4. Principles of Motion Sensing

    Principlesof Motion Sensing Various sensors capable of detecting motionin free space have been comme ...

  5. Qt4.8 移植(超详细Configure的参数)

    Qt4.8.6 configure 参数 不只是适用于Qt4.8.6,原则上适用于Qt4所有版本 Usage: configure [-h] [-prefix <dir>] [-prefi ...

  6. [LeetCode#116]Fraction to Recurring Decimal

    Problem: Given two integers representing the numerator and denominator of a fraction, return the fra ...

  7. BZOJ2375: 疯狂的涂色

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2375 小t非常喜爱画画,但是他还是一个初学者.他最近费尽千辛万苦才拜到已仙逝的达 芬奇为师(神 ...

  8. 2015第44周五Java集群技术(转)

    从http://blog.csdn.net/cdh1213/article/details/21443239上看到这篇文章,感觉很不错,找好久没找到中文出处,最早看是从http://www.these ...

  9. 如何实现View上添加标签

    效果图: 利用 https://github.com/linger1216/labelview 类库来实现 具体代码 问度娘. {LabelView label = new LabelView(thi ...

  10. 窥探Unity5渲染内部之解析UnityShaderVariables.cginc

    unity5的UnityShaderVariables.cginc比unity4大了1kb这里装着unity shader 大部分内部参数,写这个方便以后自己查询 Camera参数 uniform f ...