1789:算24

给出4个小于10个正整数,你可以使用加减乘除4种运算以及括号把这4个数连接起来得到一个表达式。现在的问题是,是否存在一种方式使得得到的表达式的结果等于24。
这里加减乘除以及括号的运算结果和运算的优先级跟我们平常的定义一致(这里的除法定义是实数除法)。
比如,对于5,5,5,1,我们知道5 * (5 – 1 / 5) = 24,因此可以得到24。又比如,对于1,1,4,2,我们怎么都不能得到24。

第一道水题就看了题解,自己觉得太不好搜了,原来是功力不够;
我们把输入都定义成double,思路是任意两个数之间计算(注意计算方式有六种),把结果存起来,并对其下标打个标记,继续作为一个新的数参与运算,注意回溯。
数据范围非常小,直接暴力即可

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
double eps=1e-6;
double a[10];
bool vis[10];
bool same(double x) {return 24.0-eps<=x && x<=24.0+eps;}
bool dfs(int num)
{if (num==4){for (int i=1; i<=4; i++)if (!vis[i] && same(a[i])) return true;return false;}for (int i=1; i<=4; i++)//枚举第一个数 if (!vis[i])for (int j=i+1; j<=4; j++)//枚举第二个数 if (!vis[j]){vis[j]=1;double tmp1=a[i],tmp2=a[j];a[i]=tmp1+tmp2;if (dfs(num+1)) return true;a[i]=tmp1-tmp2;if (dfs(num+1)) return true;a[i]=tmp2-tmp1;if (dfs(num+1)) return true;a[i]=tmp1*tmp2;if (dfs(num+1)) return true;a[i]=tmp1/tmp2;if (dfs(num+1)) return true;a[i]=tmp2/tmp1;if (dfs(num+1)) return true;vis[j]=0;a[i]=tmp1;//注意回溯 }return false;
}int main()
{while (scanf("%lf%lf%lf%lf",&a[1],&a[2],&a[3],&a[4])){if (a[1]==0&&a[2]==0&&a[3]==0&&a[4]==0) break;memset(vis,0,sizeof(vis));if (dfs(1)) printf("YES\n");else printf("NO\n");}return 0;
}

1792:迷宫

一天Extense在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由n * n的格点组成,每个格点只有2种状态,.和#,前者表示可以通行后者表示不能通行。同时当Extense处在某个格点时,他只能移动到东南西北(或者说上下左右)四个方向之一的相邻格点上,Extense想要从点A走到点B,问在不走出迷宫的情况下能不能办到。如果起点或者终点有一个不能通行(为#),则看成无法办到。

记得这种水题还是刚学bfs时经常做的呢

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int dx[5]={0,-1,0,1}, dy[5]={-1,0,1,0};
int a[110][110];
int bo,k,n,f[110][110],ha,la,hb,lb;
void dfs(int xx,int yy)
{if (bo)return;if (xx==hb&&yy==lb) {bo=1;return;}for(int i=0;i<4;i++){int x=xx+dx[i],y=yy+dy[i];if (a[x][y]){a[x][y]=0;dfs(x,y);}}
}
int main()
{cin>>k;for (int t=1;t<=k;t++){cin>>n;memset(a,0,sizeof(a));for (int i=1;i<=n;i++)for (int j=1;j<=n;j++){char ch;cin>>ch;if (ch=='.')a[i][j]=1;}cin>>ha>>la>>hb>>lb;ha++;la++;hb++;lb++;bo=0;if (!a[ha][la]||!a[hb][lb]) {cout<<"NO"<<endl;continue;}a[ha][la]=0;dfs(ha,la);if (bo) cout<<"YES"<<endl;else cout<<"NO"<<endl;}return 0;
}

1805:碎纸机

1.每次切割之前,先要给定碎纸机一个目标数,而且在每张被送入碎纸机的纸片上也需要包含一个数。
2.碎纸机切出的每个纸片上都包括一个数。
3.要求切出的每个纸片上的数的和要不大于目标数而且与目标数最接近。
举一个例子,如下图,假设目标数是50,输入纸片上的数是12346。碎纸机会把纸片切成4块,分别包含1,2,34和6。这样这些数的和是43 (= 1 + 2 + 34 + 6),这是所有的分割方式中,不超过50,而又最接近50的分割方式。又比如,分割成1,23,4和6是不正确的,因为这样的总和是34 (= 1 + 23 + 4 + 6),比刚才得到的结果43小。分割成12,34和6也是不正确的,因为这时的总和是52 (= 12 + 34 + 6),超过了50。
还有三个特别的规则:
1.如果目标数和输入纸片上的数相同,那么纸片不进行切割。
2.如果不论怎样切割,分割得到的纸片上数的和都大于目标数,那么打印机显示错误信息。
3.如果有多种不同的切割方式可以得到相同的最优结果。那么打印机显示拒绝服务信息。比如,如果目标数是15,输入纸片上的数是111,那么有两种不同的方式可以得到最优解,分别是切割成1和11或者切割成11和1,在这种情况下,打印机会显示拒绝服务信息。
为了设计这样的一个碎纸机,你需要先写一个简单的程序模拟这个打印机的工作。给定两个数,第一个是目标数,第二个是输入纸片上的数,你需要给出碎纸机对纸片的分割方式。

感觉这道搜素题还是比较好的。
自己的方法不是很好,代码很难看,有一些标记,但还是过了

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
int n,m,la,lb,a[101],b[101];
int vis[1000000],ans[100];//tong
int nowmax;
struct st{int len,a[101];
}s[1001];
int tot,id;
int calc()
{int x=n;while (x) {a[++la]=x%10; x/=10;}x=m;while (x) {b[++lb]=x%10; x/=10;}
}
bool check()
{int tmp=0;for (int i=1; i<=lb; i++) tmp+=b[i];if (tmp>n) return true;tot++;for (int i=1; i<=lb; i++) s[tot].a[i]=b[i];vis[tmp]++;nowmax=tmp; id=tot; s[tot].len=lb;return false;
}int js(int l,int r)
{int ans=0;for (int i=r; i>=l; i--)ans=(ans<<1)+(ans<<3)+b[i];return ans;
}void doit(int len)
{if (ans[len]!=lb) return;int tmp=0; tot++;for (int i=1; i<=len; i++){int tt=js(ans[i-1]+1,ans[i]);tmp+=tt;s[tot].a[i]=tt;}if (tmp>n) {tot--; return;}vis[tmp]++;s[tot].len=len;if (tmp>nowmax){nowmax=tmp; id=tot;}
}void dfs(int last,int num,int goal)
{if (num==goal+1) {doit(goal); return;}for (int i=last+1; i<=lb; i++){ans[num]=i;dfs(i,num+1,goal);}
}
void work(int num)
{dfs(0,1,num);
}
void csh()
{tot=0; id=0; nowmax=0; la=0; lb=0;memset(vis,0,sizeof(vis));
}int main()
{while (scanf("%d%d",&n,&m)){csh();if (n==0 && m==0) break;if (n==m) {printf("%d %d\n",n,m); continue;}calc();if (check()) {printf("error\n"); continue;}for (int i=lb-1; i>=lb/la-1; i--)work(i);if (vis[nowmax]>1) {printf("rejected\n"); continue;}printf("%d ",nowmax);for (int i=s[id].len; i>=1; i--) printf("%d ",s[id].a[i]); printf("\n");}
}

1818:红与黑

有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻的黑色瓷砖移动。请写一个程序,计算你总共能够到达多少块黑色的瓷砖。

dfs水题,直接计数即可

#include<iostream>
#include<cstring>
using namespace std;
int a[22][22],w,h,total;
void dfs(int x,int y)
{total++;a[x][y]=0;if(a[x+1][y]) dfs(x+1,y);if(a[x-1][y]) dfs(x-1,y);if(a[x][y+1]) dfs(x,y+1);if(a[x][y-1]) dfs(x,y-1);
}
int main()
{int x,y;cin>>w>>h;char a1;while(!(w==0&&h==0)){total=0;memset(a,0,sizeof(a));for(int i=1;i<=h;i++)for(int j=1;j<=w;j++){cin>>a1;if(a1=='.'||a1=='@')a[i][j]=1;if(a1=='@'){x=i;y=j;}}dfs(x,y);cout<<total<<endl;cin>>w>>h;}
}

2971:抓住那头牛

农夫知道一头牛的位置,想要抓住它。农夫和牛都位于数轴上,农夫起始位于点N(0<=N<=100000),牛位于点K(0<=K<=100000)。农夫有两种移动方式:
1、从X移动到X-1或X+1,每次移动花费一分钟
2、从X移动到2*X,每次移动花费一分钟
假设牛没有意识到农夫的行动,站在原地不动。农夫最少要花多少时间才能抓住牛?

这道水题还做了这么久。。
首先是没有开一个vis数组标记,T的很惨
开了之后vis开小了RE,应该两倍大
然后对于入队条件的判断,是否等于0,最大值的判断
总之,水题不能1A,就是失败

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
int n,m,ans;
bool vis[1000100];
struct st{int step,v;
};
queue <st> q;
void bfs()
{st a; a.step=0; a.v=n;vis[n]=true;q.push(a);while (!q.empty()){st now=q.front(); q.pop();
//      printf("%d %d\n",now.step,now.v);if (now.v==m) {ans=now.step; return;}st tmp;tmp.step=now.step+1; tmp.v=now.v+1; if (tmp.v>=0 && !vis[tmp.v]){q.push(tmp);vis[tmp.v]=true;}tmp.step=now.step+1; tmp.v=now.v-1; if (tmp.v>=0 && !vis[tmp.v]){q.push(tmp);vis[tmp.v]=true;}tmp.step=now.step+1; tmp.v=now.v*2; if (tmp.v<=100000 && !vis[tmp.v]){q.push(tmp);vis[tmp.v]=true;}}
}int main()
{scanf("%d%d",&n,&m);if (n==m) {printf("0"); return 0;}bfs();printf("%d",ans);return 0;
}

2990:符号三角形

符号三角形的第1行有n个由“+”和”-“组成的符号 ,以后每行符号比上行少1个,2个同号下面是”+“,2个异号下面是”-“ 。计算有多少个不同的符号三角形,使其所含”+“ 和”-“ 的个数相同。
n=7时的1个符号三角形如下:
+ + - + - + +
+ - - - - +
- + + + -
- + + -
- + -
- -
+

这道搜素题还是挺不错的,刚开始没有想出思路。
我们把+-分别看成01,他们之间的操作就是异或
我们同样可以发现,当第一行确定了,这一行就都确定了 (是不是和扫雷有点像)
我们考虑把三角形倒过来,推上一行。注意回溯的过程
输出:c[n];

void dfs(int x)
{if(x>n) return;for(int i=0; i<=1; i++) {a[1][x]=i;tot+=i;for(int j=2; j<=x; j++) {a[j][x-j+1]=a[j-1][x-j+2]^a[j-1][x-j+1];tot+=a[j][x-j+1];}if(tot*2 == n*(n+1)/2)  c[x]++;dfs(x+1);tot-=i;for(int j=2; j<=x; j++) {a[j][x-j+1]=a[j-1][x-j+2]^a[j-1][x-j+1];tot-=a[j][x-j+1];}}
}

666:放苹果

把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。

用搜索写的话,就是一个枚举组合的东西
用dp写的话,就是一个水水的线性dp
分解成子问题也可以用分治来写

#include<iostream>
using namespace std;
int t,n,m,c;
void search(int k,int f,int t)
{if(k==0) {c++;return;}if(f==m){if(k==0) c++;return;}for(int i=t;i<=k;i++)if(k>=i)search(k-i,f+1,i);
}
int main()
{cin>>t;for (int i=1;i<=t;i++){c=0;cin>>n>>m;search(n,0,1);cout<<c<<endl;}
}#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int dp[1000][1000]={0};//dp[m][n]
int main()
{int t,m,n;scanf("%d",&t);for(int i=1;i<=t;i++){memset(dp,0,sizeof(dp));scanf("%d%d",&m,&n);m+=n;for(int j=0;j<=m;j++){dp[j][j]=1;if(j>0)dp[j][1]=1;}for(int j=1;j<=m;j++){for(int k=1;k<=n&&k<=j;k++){dp[j][k]=dp[j-1][k-1]+dp[j-k][k];}}printf("%d\n",dp[m][n]);}return 0;
}#include<cstdio>
int value(int m,int n)
{if(m==0||n==1)return 1;else{if(m<n)return value(m,m);elsereturn value(m-n,n)+value(m,n-1);}
}
int main()
{int t;int m,n;scanf("%d",&t);for(int i=0;i<t;i++){scanf("%d%d",&m,&n);printf("%d\n",value(m,n));}return 0;
}

1819:木棒

乔治拿来一组等长的木棒,将它们随机地裁断,使得每一节木棍的长度都不超过50个长度单位。然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。请你设计一个程序,帮助乔治计算木棒的可能最小长度。每一节木棍的长度都用大于零的整数表示。

这道题还做了好长时间呢
考虑使用二分——二分出一个值,判断是否可以拼凑出来
然而考虑是否具有单调性?即小的不行那么解就一定在大的里面找?
应该不是 况且check的过程非常复杂
然后想到了另一种方法;
答案肯定是在Max–Sum之中的Sum的倍数中产生并且尽量小,所以我们只需要枚举这些数就好了
先从小到大排序,在check的时候贪心选大的接上。
如果能拼出一个原始木棍一定不会对后面的造成影响
但是这样T掉了,查看了题解,采用了题解的更优的搜索方法

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
int cmp(const void*p1,const void*p2)
{return *(int*)p2-*(int*)p1;
}
int a[100],v[100];
int n,len,s,tot,min;
bool dfs(int k,int mi,int left)
{int i;if(left==min) return 1;for(i=k;i<=n;i++)if(!v[i]&&a[i]<=mi){v[i]=1;if(a[i]==mi&&dfs(1,len,left-a[i]))return 1;else if(dfs(i+1,mi-a[i],left-a[i]))return 1;v[i]=0;if(a[i]==min)return 0;if(left==tot)return 0;if(mi==len)  return 0;while(a[i+1]==a[i])i++;}return 0;
}
int main()
{int i,res;while(scanf("%d",&n),n){tot=0;for(i=1;i<=n;i++){scanf("%d",&a[i]);tot+=a[i];}qsort(a+1,n,sizeof(a[0]),cmp);len=a[1];res=len;memset(v,0,sizeof(v));res=tot;for(;len<tot;len++)if(tot%len==0&&dfs(1,len,tot)){res=len;break;}printf("%d\n",res);}return 0;
}

1814:恼人的青蛙

构造出青蛙穿越稻田时的行走路径,并且只关心那些在穿越稻田时至少踩踏了3棵水稻的青蛙。因此,每条青蛙行走路径上至少包括3棵被踩踏的水稻。而在一条青蛙行走路径的直线上,也可能会有些被踩踏的水稻不属于该行走路径
①不是一条行走路径:只有两棵被踩踏的水稻;
②是一条行走路径,但不包括(2,6)上的水道;
③不是一条行走路径:虽然有3棵被踩踏的水稻,但这三棵水稻之间的距离间隔不相等。
请你写一个程序,确定:在一条青蛙行走路径中,最多有多少颗水稻被踩踏。例如,图4的答案是7,因为第6行上全部水稻恰好构成一条青蛙行走路径。

有一种思路枚举任意两个点 O(n^2) 找这条路上的点O(n^3) 然后标记这条路上的所有两个点之间的关系 O(m^2/2)
总的复杂度大概是 O(n^4) 625e12
其实不必On找路径上的点,直接加差即可,原本以为这样复杂度会很高

#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <stdlib.h>
#include <math.h>
using namespace std;
struct bode
{  int x,y;
} node[5005];
bool vis[5005][5005];
int n,disx,disy,r,c,tmpx,tmpy,max1=0,cnt;
int cmp(const bode &a,const bode &b)
{  if(a.y==b.y)return a.x<b.x;  else return a.y<b.y;
}
int main()
{  scanf("%d%d",&r,&c);  scanf("%d",&n);  memset(vis,false,sizeof(vis));  for(int i=0; i<n; i++)  {  scanf("%d%d",&node[i].x,&node[i].y);  vis[node[i].x][node[i].y]=true;  }  sort(node,node+n,cmp);  max1=0;  for(int i=0;i<n;i++)  {  for(int j=i+1;j<n;j++)  {  disx=node[j].x-node[i].x;  disy=node[j].y-node[i].y;  if(node[i].x-disx>0&&node[i].x-disx<=r&&node[i].y-disy>0&&node[i].y-disy<=c)continue;  tmpx=node[j].x+disx;  tmpy=node[j].y+disy;  cnt=0;  while(tmpx>0&&tmpx<=r&&tmpy>0&&tmpy<=c)  {  if(vis[tmpx][tmpy])cnt++;  else  {  cnt=0;  break;  }  tmpx+=disx;  tmpy+=disy;  }  max1=max(max1,cnt);  }  }  if(max1)  printf("%d\n",max1+2);  else puts("0");  return 0;
}  

NoiOpenjudge水题选刷之_搜索相关推荐

  1. 闲来无事刷水题、简单博弈论专题、sg函数、洛谷

    记 今天闲来无事,不想刷codeforces了,到洛谷提高组训练营找几道水题刷着玩玩(虽然自己早已过了打OI的年纪)- 简单博弈论专题 P1199 三国游戏 这么考虑,由于电脑总是不能让我搭配出当前能 ...

  2. 图论刷水题记录(二)(最短路-----SPFA算法)

    继第一篇的后续,又来刷水题了,写的是SPFA算法,这个算法的复杂度比较玄学,感觉能不用就不用了,但是他的好处就是可以判断负圈. 3月26日: 1.POJ 1847 Tram 题意:在一个交通网络上有N ...

  3. 图论刷水题记录(一)(最短路-----dijkstra算法)

    最近实在不知道干些什么,感觉自己除了水题什么都不会做,算了去刷一刷图论的水题吧本来想合起来一起发,想了想太长的话以后看起来也不方便,题目所以今天晚上就先发了dij部分,由上到下由易变难. 1.POJ ...

  4. 搜索 由浅入深 之一 水题

    搜索很重要,是很难学的算法,能看懂很简单,但是要想真正做出题来就比较困难了,那么,我们现在就水题开始研究搜索. 水题之: 1024: [SCOI2009]生日快乐 Time Limit: 1 Sec  ...

  5. 1800: 少水群多刷题

     1800: 少水群多刷题 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 700  Solved: 321 SubmitStatusWeb Boa ...

  6. ZZULIOJ 1800: 少水群多刷题

    题目描述 输入 多实例,读取到文件尾结束. 每个实例输入一个正整数n 输出 对每个实例:输出n行"年轻人要少水群多刷题!"(不要输出引号) 每个实例后面输出一个空行. 样例输入 1 ...

  7. ZZULIOJ 1800 少水群多刷题

    1800: 少水群多刷题 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 686  Solved: 314 SubmitStatusWeb Board ...

  8. ZHOJ_#12832. 简单的大背包_水题

    ZHOJ_#12832. 简单的大背包_水题 #12832. 简单的大背包 ID: 12832传统题2000ms1024MiB上传者:ZHtwinkle 说明 你有一个容积为 nn 的背包.现有两种物 ...

  9. CodeForces Canada Cup 2016 A、B水题 _(:з」∠)_

    哭哭哭哭哭哭哭 又降了4...... 这次吸取的教训是...本来就是个做题慢的傻逼....一定要准时题目一开就开始做.....不然就等着降名次吧,..... 开始四十多分钟才开进去的.....再给我四 ...

最新文章

  1. 如果你的云服务商倒闭该怎么办?
  2. mysql的连接leftjion,mysql的表连接(left|right)join
  3. 用tftp 下载/更新ios和配置文件
  4. Anaconda-- conda 创建、激活、退出、删除虚拟环境
  5. 在 Windows 中,当一个应用程序窗口被关闭,该应用程序将会保留在哪里?
  6. Mac AndroidStudio常用快捷键
  7. dsd语言证书c1是什么,DSD一级德语语言证书考试在嘉兴高级中学举行
  8. 算法工程师进化-基础理论
  9. 【mysql】悲观锁和乐观锁的实现原理
  10. disable jboss JMXInvokerServlet .
  11. css3美话网页元素
  12. xlsx文件打开乱码_excel打开xls文件全是乱码怎么办?excel打开xls乱码的修复方法
  13. dosbox详细安装级及使用
  14. 小米路由器r2d_小米路由器R2D亮黄灯维修
  15. 高清图片、视频素材免费下载
  16. 时间一天天过去,好像什么都没变。
  17. 像外行一样思考,像专家一样实践——科研成功之道(修订版)
  18. Zabbix实现短信报警设置(实战)
  19. 关于Adobe flash player 本地播放器
  20. 「Python|场景案例」如何获取音视频中声音片段的起止时间?

热门文章

  1. 超详细!动画图解「合并 K 个排序链表」
  2. JMeter学习-005-JMeter 配置元件实例之 - CSV Data Set Config 参数化配置
  3. java获取文件电脑路径
  4. python opc服务器和客户端互相发送信息并给出实例
  5. 工赋开发者社区 | 让小型企业提高 20 倍效率的统一技术栈
  6. 火狐怎么导入收藏夹_火狐浏览器怎么把网页添加到收藏夹
  7. 企微创建自建应用-关联html/小程序
  8. pta c语言段错误,PTA常见错误
  9. 八问数据中台:关于数据中台你想知道的都在这里!
  10. 抖音作品和直播间如何获取更多流量