9.28noip模拟试题
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模拟试题的更多相关文章
- 9.28NOIP模拟题
9.28NOIP模拟题 题目 哈 哈哈 哈哈哈 英文题目与子目录名 ha haha hahaha 单个测试点时间限制 1秒 1秒 1秒 内存限制 256M 128M 64M 测试点数目 10 10 1 ...
- 模拟试题C
模拟试题C 一.单项选择题(2′*14 =28′) 1.双线性法向插值法(Phong Shading)的优点是( ) A)法向计算精确 B)高光域准确 C)对光源和视点没有限制 D)速度较快 2.用编 ...
- 模拟试题B
模拟试题B 一.单项选择题(2′*8 =16′) 1.灰度等级为256级,分辨率为2048*1024的显示器,至少需要的帧缓存容量为( ) A)512KB B)1MB C)2MB D)3MB 2.在多 ...
- 模拟试题A
模拟试题A 一.单项选择题(2′*12=24′) 1.下面各种坐标变换中,会产生变换前后维度的改变的是( ) A)建模变换 B)观察变换 C)投影变换 D)视口变换 2.下列描述深度缓冲消隐算法的特点 ...
- CCF 模拟试题——出现次数最多的数 官方答案解析及自己写的正确答案
前几天知道的CCF计算机职业资格认证考试,觉得好像比软考含金量高一些,就去了解了一下,做了模拟试题中的 “出现次数最多的数” 这道题,我的算法和官方答案算法不同,个人觉得觉得官方的好一点,没那么繁琐, ...
- 11.9 noip模拟试题
NOIP2016 模拟赛——那些年,我们学过的文化课背单词(word.c/cpp/pas)[题目描述]fqk 退役后开始补习文化课啦, 于是他打开了英语必修一开始背单词. 看着满篇的单词非常头疼, 而 ...
- 10.26 noip模拟试题
enc[问题背景]zhx 和他的妹子聊天.[问题描述]考虑一种简单的加密算法.假定所有句子都由小写英文字母构成,对于每一个字母,我们将它唯一地映射到另一个字母.例如考虑映射规则:a->b, b- ...
- 9.29noip模拟试题
环上的游戏(cycle) 有一个取数的游戏.初始时,给出一个环,环上的每条边上都有一个非负整数.这些整数中至少有一个0.然后,将一枚硬币放在环上的一个节点上.两个玩家就是以这个放硬币的节点为起点开始这 ...
- 9.20 noip模拟试题
Problem 1 双色球(ball.cpp/c/pas) [题目描述] 机房来了新一届的学弟学妹,邪恶的chenzeyu97发现一位学弟与他同名,于是他当起了善良的学长233 “来来来,学弟,我 ...
随机推荐
- ibatis 中isNull, isNotNull与isEmpty, isNotEmpty区别
在iBATIS中isNull用于判断参数是否为Null,isNotNull相反 isEmpty判断参数是否为Null或者空,满足其中一个条件则其true isNotEmpty相反,当参数既不为Null ...
- 使用lombok
Lombok是一种JavaArchive(JAR)文件,可用来消除Java代码的冗长.通过在开发环境中实现Lombok,开发人 员可以节省构建诸如hashCode()和equals()这样的方法以及以 ...
- Unicode(UTF-8, UTF-16)令人混淆的概念
为啥需要Unicode 我们知道计算机其实挺笨的,它只认识0101这样的字符串,当然了我们看这样的01串时肯定会比较头晕的,所以很多时候为了描述简单都用十进制,十六进制,八进制表示.实际上都是等价的, ...
- Scarborough Fair 绝美天籁
很少见的男声唱法,而且还古色古香: https://www.youtube.com/watch?v=sgbo2QWLBzI https://www.youtube.com/watch?v=-BakWV ...
- PHP+MYSQL实现输出打印数据库表结构和输出表内容
效果图1 <form id="form1" name="form1" action="2.php" method="get& ...
- restful风格,restcontroller与controller
restful风格,restcontroller与controller 初步接触springmvc的时候,被要求使用restful风格,彼时一头雾水,不懂何谓restful,参阅了很多资料,慢慢的接触 ...
- 14.5.5 Deadlocks in InnoDB
14.5.5 Deadlocks in InnoDB 14.5.5.1 An InnoDB Deadlock Example 14.5.5.2 Deadlock Detection and Rollb ...
- 【HDOJ】3592 World Exhibition
基础差分约束. /* 3592 */ #include <iostream> #include <algorithm> #include <queue> #incl ...
- bzoj3083 3306
又见bzoj的语言歧视,囧……bzoj3083过了本地的数据在上面出现各种奇葩的TLE835083 phile 3083 Time_Limit_Exceed 17092 kb 4872 ms Pasc ...
- crontab(linux下定时执行任务命令)
在linux在可以通过在脚本里(列如sh)写如日常需要进行的操作,然后通过crontab定时运行脚本. Linux下的任务调度分为两类,系统任务调度和用户任务调度. 系统任务调度:系统周期性所要执行的 ...