搜索

DFS

  1. void dfs(int x)
  2. {
  3. vis[x] = 1;
  4. for(int i = head[x];i;i = e[i].x)
  5. {
  6. if(!vis[e[i].t])
  7. {
  8. dfs(e[i].t);
  9. }
  10. }
  11. }

例1 P1101 单词方阵

题目描述

给一n×n的字母方阵,内可能蕴含多个“yizhong”单词。单词在方阵中是沿着同一方向连续摆放的。摆放可沿着 8个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间可以交叉,因此有可能共用字母。输出时,将不是单词的字母用*代替,以突出显示单词。例如:

  1. 输入:
  2. 8 输出:
  3. qyizhong *yizhong
  4. gydthkjy gy******
  5. nwidghji n*i*****
  6. orbzsfgz o**z****
  7. hhgrhwth h***h***
  8. zzzzzozo z****o**
  9. iwdfrgng i*****n*
  10. yyyygggg y******g

输入输出格式

输入格式:

第一行输入一个数n。(7≤n≤100)。

第二行开始输入n×n的字母矩阵。

输出格式:

突出显示单词的n×n矩阵。

输入输出样例

输入样例#1: 复制

  1. 7
  2. aaaaaaa
  3. aaaaaaa
  4. aaaaaaa
  5. aaaaaaa
  6. aaaaaaa
  7. aaaaaaa
  8. aaaaaaa

输出样例#1: 复制

  1. *******
  2. *******
  3. *******
  4. *******
  5. *******
  6. *******
  7. *******

输入样例#2: 复制

  1. 8
  2. qyizhong
  3. gydthkjy
  4. nwidghji
  5. orbzsfgz
  6. hhgrhwth
  7. zzzzzozo
  8. iwdfrgng
  9. yyyygggg

输出样例#2: 复制

  1. *yizhong
  2. gy******
  3. n*i*****
  4. o**z****
  5. h***h***
  6. z****o**
  7. i*****n*
  8. y******g

标程

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=110;
  4. char ss[maxn][maxn],zz[]="yizhong";
  5. int vis[maxn][maxn];
  6. int fuck[][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
  7. struct wahaha
  8. {
  9. int a,b;
  10. }c[maxn];
  11. void dfs_one(int n);
  12. void dfs_tow(int x,int y,int k,int cnt,wahaha c[]);
  13. void dfs_one(int n){
  14. for(int i=0;i< n;++i){
  15. for(int j=0;j< n;++j){
  16. if(ss[i][j]=='y'){
  17. for(int k = 0; k < 8; k++)
  18. {
  19. int x=i+fuck[k][0];
  20. int y=j+fuck[k][1];
  21. if(ss[x][y]=='i') {
  22. dfs_tow(i,j,k,0,c);
  23. }
  24. }
  25. }
  26. }
  27. }
  28. }
  29. void dfs_tow(int x,int y,int k,int cnt,wahaha c[]){
  30. if(cnt==7) {
  31. for(int i=0;i<7;++i){
  32. vis[c[i].a][c[i].b]=1;
  33. }
  34. }
  35. else{
  36. int dx=x+fuck[k][0];
  37. int dy=y+fuck[k][1];
  38. if(cnt==6||ss[dx][dy]==zz[cnt+1]){
  39. c[cnt].a=x;c[cnt].b=y;
  40. dfs_tow(dx,dy,k,cnt+1,c);
  41. }
  42. }
  43. }
  44. inline void init()
  45. {
  46. int n;
  47. scanf("%d",&n);
  48. for(int i=0;i<n;++i){
  49. scanf("%s",&ss[i]);
  50. }
  51. memset(vis,0,sizeof(vis));
  52. dfs_one(n);
  53. for(int i=0;i<n;++i){
  54. for(int j=0;j<n;++j){
  55. if(vis[i][j]) printf("%c",ss[i][j]);
  56. else printf("*");
  57. }
  58. printf("\n");
  59. }
  60. }
  61. int main(int argc, char const *argv[])
  62. {
  63. init();
  64. return 0;
  65. }

例2 P1605 迷宫

题目背景

给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过。给定起点坐标和

终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案。在迷宫

中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。

1≤N,M≤5

输入输出格式

输入格式:

【输入】

第一行N、M和T,N为行,M为列,T为障碍总数。第二行起点坐标SX,SY,终点

坐标FX,FY。接下来T行,每行为障碍点的坐标。

输出格式:

【输出】

给定起点坐标和终点坐标,问每个方格最多经过1次,从起点坐标到终点坐标的方

案总数。

输入输出样例

输入样例#1: 复制

  1. 2 2 1
  2. 1 1 2 2
  3. 1 2

输出样例#1: 复制

1

标程

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int SX,SY,FX,FY;
  4. int MAP[6][6],vis[6][6];
  5. int dx[]={0,0,-1,1},dy[]={-1,1,0,0};
  6. int ans=0;
  7. int n,m,t;
  8. void dfs(int x,int y)
  9. {
  10. if(x==FX && y==FY)
  11. {
  12. ans++;
  13. return ;
  14. }
  15. else
  16. {
  17. for(int i = 0; i <= 3; i++)
  18. {
  19. if(vis[x+dx[i]][y+dy[i]]==0 && MAP[x+dx[i]][y+dy[i]]==1)
  20. {
  21. vis[x][y]=1;
  22. dfs(x+dx[i],y+dy[i]);
  23. vis[x][y]=0;
  24. }
  25. }
  26. }
  27. }
  28. inline void init()
  29. {
  30. scanf("%d%d%d",&n,&m,&t);
  31. for(int i=1;i<=n;i++)
  32. {
  33. for(int j=1;j<=m;j++)
  34. {
  35. MAP[i][j]=1;
  36. }
  37. }
  38. scanf("%d%d%d%d",&SX,&SY,&FX,&FY);
  39. for(int i=1;i<=t;++i)
  40. {
  41. int x,y;
  42. scanf("%d%d",&x,&y);
  43. MAP[x][y]=0;
  44. }
  45. memset(vis,0,sizeof(vis));
  46. dfs(SX,SY);
  47. printf("%d",ans);
  48. }
  49. int main(int argc, char const *argv[])
  50. {
  51. init();
  52. return 0;
  53. }

例3 P1019 单词接龙

题目描述

单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beastbeast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如atatide 间不能相连。

输入输出格式

输入格式:

输入的第一行为一个单独的整数n (n≤20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在.

输出格式:

只需输出以此字母开头的最长的“龙”的长度

输入输出样例

输入样例#1: 复制

  1. 5
  2. at
  3. touch
  4. cheat
  5. choose
  6. tact
  7. a

输出样例#1: 复制

23

说明

(连成的“龙”为atoucheatactactouchoose

NOIp2000提高组第三题

标程

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=105;
  4. char a[55][55],b[55];
  5. int n,np=0,first[maxn],ans=100000,vis[maxn];
  6. struct edge{
  7. int to,next,w;
  8. }E[maxn<<1];
  9. void addedge(int u,int v,int w)
  10. {
  11. E[++np]=(edge){v,first[u],w};
  12. first[u]=np;
  13. // printf("%d %d %d\n",u,v,w);
  14. }
  15. void dfs(int i,int l)
  16. {
  17. vis[i]++;//技巧
  18. ans=max(ans,l);
  19. for(int p=first[i];p;p=E[p].next)
  20. {
  21. int j=E[p].to,w=E[p].w;
  22. if(vis[j]==2) continue;
  23. dfs(j,l+w);
  24. }
  25. vis[i]--;
  26. }
  27. int check(int i,int j)
  28. {
  29. int lenj=strlen(a[j]);
  30. int leni=strlen(a[i]);
  31. int ans=0;
  32. int k;
  33. for(k=0;k+1<min(leni,lenj);k++)
  34. {
  35. int ok=1;
  36. for(int r=0;r<=k;r++)
  37. {
  38. if(a[i][leni-1-k+r]!=a[j][r]) {ok=0;break;}
  39. }
  40. if(ok){ ans=k+1;break;}
  41. }
  42. if(ans==0) return 0;
  43. return lenj-ans;
  44. }
  45. void init()
  46. {
  47. scanf("%d",&n);
  48. for(int i=1;i<=n;i++)
  49. {
  50. scanf("%s",&a[i]);memcpy(a[i+n],a[i],sizeof(a[i]));
  51. }
  52. scanf("%s",a[2*n+1]);
  53. for(int i=1;i<=n;i++)
  54. for(int j=1;j<=n;j++)
  55. {
  56. int w=check(i,j);
  57. if(w) addedge(i,j,w);
  58. }
  59. for(int i=1;i<=n;i++)//最后一个点编号随意
  60. {
  61. if(a[i][0]==a[2*n+1][0]) addedge(2*n+1,i,strlen(a[i])-1);
  62. }
  63. }
  64. int main()
  65. {
  66. init();
  67. ans=0;
  68. dfs(2*n+1,1);
  69. printf("%d",ans);
  70. return 0;
  71. }

例4 P1162 马的遍历

题目描述

由数字0组成的方阵中,有一任意形状闭合圈,闭合圈由数字1构成,围圈时只走上下左右4个方向。现要求把闭合圈内的所有空间都填写成2.例如:6×6的方阵(n=6),涂色前和涂色后的方阵如下:

  1. 0 0 0 0 0 0
  2. 0 0 1 1 1 1
  3. 0 1 1 0 0 1
  4. 1 1 0 0 0 1
  5. 1 0 0 0 0 1
  6. 1 1 1 1 1 1
  1. 0 0 0 0 0 0
  2. 0 0 1 1 1 1
  3. 0 1 1 2 2 1
  4. 1 1 2 2 2 1
  5. 1 2 2 2 2 1
  6. 1 1 1 1 1 1

输入输出格式

输入格式:

每组测试数据第一行一个整数n(1≤n≤30)

接下来n行,由0和1组成的n×n的方阵。

方阵内只有一个闭合圈,圈内至少有一个0。

//感谢黄小U饮品指出本题数据和数据格式不一样. 已修改(输入格式)

输出格式:

已经填好数字2的完整方阵。

输入输出样例

输入样例#1: 复制

  1. 6
  2. 0 0 0 0 0 0
  3. 0 0 1 1 1 1
  4. 0 1 1 0 0 1
  5. 1 1 0 0 0 1
  6. 1 0 0 0 0 1
  7. 1 1 1 1 1 1

输出样例#1: 复制

  1. 0 0 0 0 0 0
  2. 0 0 1 1 1 1
  3. 0 1 1 2 2 1
  4. 1 1 2 2 2 1
  5. 1 2 2 2 2 1
  6. 1 1 1 1 1 1

标程

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int maps[100][100],mapCLON[100][100]={0};
  4. int n,x,y;
  5. void dfs(int x,int y)
  6. {
  7. if(x>n||x<1||y>n||y<1||maps[x][y]!=0)//判断是否越界
  8. return;
  9. maps[x][y]=1;
  10. dfs(x+1,y);
  11. dfs(x-1,y);
  12. dfs(x,y+1);
  13. dfs(x,y-1);//四个方向
  14. }
  15. inline void init()
  16. {
  17. scanf("%d",&n);
  18. for(int i=1;i<=n;i++)
  19. for(int j=1;j<=n;j++)
  20. {
  21. cin>>maps[i][j];
  22. if(maps[i][j]==1) mapCLON[i][j]=-1;//b用来存原来的位置
  23. }
  24. int flag=0;
  25. for(int i=1;i<=n;i++)
  26. {
  27. if(maps[i][1]!=1) dfs(i,1);
  28. if(maps[i][n]!=1) dfs(i,n);//搜第i行的第一列和第n列
  29. }
  30. for(int i=1;i<=n;i++)
  31. {
  32. if(maps[1][i]!=1) dfs(1,i);
  33. if(maps[n][i]!=1) dfs(n,i);//搜第i列的第一行和第n行
  34. }
  35. for(int i=1;i<=n;i++)
  36. {
  37. for(int j=1;j<=n;j++)
  38. {
  39. if(mapCLON[i][j]==-1) printf("1 ");
  40. else if(maps[i][j]==0) printf("2 ");
  41. else printf("0 ");
  42. }
  43. printf("\n");
  44. }
  45. }
  46. int main()
  47. {
  48. init();
  49. return 0;
  50. }

剪枝优化

例1 P1433 吃奶酪

题目描述

房间里放着n块奶酪。一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在(0,0)点处。

输入输出格式

输入格式:

第一行一个数n (n<=15)

接下来每行2个实数,表示第i块奶酪的坐标。

两点之间的距离公式=sqrt((x1-x2)(x1-x2)+(y1-y2)(y1-y2))

输出格式:

一个数,表示要跑的最少距离,保留2位小数。

输入输出样例

输入样例#1: 复制

  1. 4
  2. 1 1
  3. 1 -1
  4. -1 1
  5. -1 -1

输出样例#1: 复制

7.41

标程

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int n,vis[1001];
  4. double x[100],y[20];
  5. double dis[1001][1001];
  6. double ans=0x3f3f3f;
  7. inline void init()
  8. {
  9. cin>>n;
  10. for(int i=1;i<=n;i++)
  11. cin>>x[i]>>y[i];
  12. x[0]=0;y[0]=0;
  13. for(int i=0;i<=n;i++)
  14. for(int j=0;j<=n;j++)
  15. dis[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
  16. }
  17. void dfs(int step,int now,double length)
  18. {
  19. if(length>ans)
  20. return;
  21. if(step==n)
  22. {
  23. ans=min(ans,length);
  24. return;
  25. }
  26. for(int i=1;i<=n;i++)
  27. if(!vis[i])
  28. {
  29. vis[i]=1;
  30. dfs(step+1,i,length+dis[now][i]);
  31. vis[i]=0;
  32. }
  33. }
  34. int main(void)
  35. {
  36. init();
  37. dfs(0,0,0.0);
  38. printf("%.2f",ans);
  39. return 0;
  40. }

例2 P1312 MaYan游戏

题目描述

Mayan puzzle是最近流行起来的一个游戏。游戏界面是一个7 行5×5列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上。游戏通关是指在规定的步数内消除所有的方块,消除方块的规则如下:

1 、每步移动可以且仅可以沿横向(即向左或向右)拖动某一方块一格:当拖动这一方块时,如果拖动后到达的位置(以下称目标位置)也有方块,那么这两个方块将交换位置(参见输入输出样例说明中的图6到图7 );如果目标位置上没有方块,那么被拖动的方块将从原来的竖列中抽出,并从目标位置上掉落(直到不悬空,参见下面图1 和图2);

2 、任一时刻,如果在一横行或者竖列上有连续三个或者三个以上相同颜色的方块,则它们将立即被消除(参见图1 到图3)。

注意:

a) 如果同时有多组方块满足消除条件,几组方块会同时被消除(例如下面图4 ,三个颜色为1 的方块和三个颜色为 2 的方块会同时被消除,最后剩下一个颜色为2的方块)。

b) 当出现行和列都满足消除条件且行列共享某个方块时,行和列上满足消除条件的所有方块会被同时消除(例如下面图5 所示的情形,5 个方块会同时被消除)。

3 、方块消除之后,消除位置之上的方块将掉落,掉落后可能会引起新的方块消除。注意:掉落的过程中将不会有方块的消除。

上面图1 到图 3 给出了在棋盘上移动一块方块之后棋盘的变化。棋盘的左下角方块的坐标为(0, 0 ),将位于(3, 3 )的方块向左移动之后,游戏界面从图 1 变成图 2 所示的状态,此时在一竖列上有连续三块颜色为4 的方块,满足消除条件,消除连续3 块颜色为4 的方块后,上方的颜色为3 的方块掉落,形成图 3 所示的局面。

输入输出格式

输入格式:

共 6 行。

第一行为一个正整数n,表示要求游戏通关的步数。

接下来的5行,描述7×5 的游戏界面。每行若干个整数,每两个整数之间用一个空格隔开,每行以一个0 结束,自下向上表示每竖列方块的颜色编号(颜色不多于10种,从1开始顺序编号,相同数字表示相同颜色)。

输入数据保证初始棋盘中没有可以消除的方块。

输出格式:

如果有解决方案,输出n行,每行包含 3 个整数x,y,g表示一次移动,每两个整数之间用一个空格隔开,其中(x,y)表示要移动的方块的坐标,g 表示移动的方向,1 表示向右移动,−1表示向左移动。注意:多组解时,按照x为第一关健字,y为第二关健字,1优先于−1 ,给出一组字典序最小的解。游戏界面左下角的坐标为(0,0)。

如果没有解决方案,输出一行,包含一个整数−1。

输入输出样例

输入样例#1: 复制

  1. 3
  2. 1 0
  3. 2 1 0
  4. 2 3 4 0
  5. 3 1 0
  6. 2 4 3 4 0

输出样例#1: 复制

  1. 2 1 1
  2. 3 1 1
  3. 3 0 1

说明

【输入输出样例说明】

按箭头方向的顺序分别为图6到图11

样例输入的游戏局面如上面第一个图片所示,依次移动的三步是:(2,1)处的方格向右移动,(3,1)处的方格向右移动,(3,0)(3,0)处的方格向右移动,最后可以将棋盘上所有方块消除。

【数据范围】

对于30%的数据,初始棋盘上的方块都在棋盘的最下面一行;

对于100%的数据,0<n≤5 。

noip2011提高组day1第3题

标程

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define il inline
  4. int n;
  5. int mapp[10][10],ans[10][10],last[10][10][10],tong[10][10];
  6. il int read()
  7. {
  8. int X=0,w=0; char ch=0;
  9. while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
  10. while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
  11. return w?-X:X;
  12. }
  13. il bool reover()
  14. {
  15. bool flag = 1;
  16. for(int i = 1;i <= 5;++i)
  17. for(int j = 1;j <= 7;++j)
  18. {
  19. if(i-1 >= 1 && i+1 <= 5 && mapp[i][j] && mapp[i][j] == mapp[i-1][j] && mapp[i][j] == mapp[i+1][j])
  20. {
  21. tong[i][j] = 1;
  22. tong[i-1][j] = 1;
  23. tong[i+1][j] = 1;
  24. flag = 0;
  25. }
  26. if(j-1 >= 1 && j+1 <= 7 && mapp[i][j] && mapp[i][j] == mapp[i][j-1] && mapp[i][j] == mapp[i][j+1])
  27. {
  28. tong[i][j] = 1;
  29. tong[i][j-1] = 1;
  30. tong[i][j+1] = 1;
  31. flag = 0;
  32. }
  33. }
  34. if(flag) return 0;
  35. for(int i = 1;i <= 5;++i)
  36. for(int j = 1;j <= 7;++j)
  37. {
  38. if(tong[i][j])
  39. {
  40. mapp[i][j] = 0;
  41. tong[i][j] = 0;
  42. }
  43. }
  44. return 1;
  45. }
  46. //玩完了
  47. il bool gameover()
  48. {
  49. for(int i = 1;i <= 5;++i)
  50. if(mapp[i][1]) return 0;
  51. return 1;
  52. }
  53. //记录操作(搜索回溯还原)
  54. il void copy (int x)
  55. {
  56. for(int i = 1;i <= 5;++i)
  57. for(int j = 1;j <= 7;++j)
  58. {
  59. last[x][i][j] = mapp[i][j];
  60. }
  61. }
  62. //下沉操作
  63. il void update()
  64. {
  65. for(int i = 1;i <= 5;++i)
  66. {
  67. int flag = 0;
  68. for(int j = 1;j <= 7;++j)
  69. {
  70. if(!mapp[i][j]) flag++;
  71. else
  72. {
  73. if(!flag) continue;
  74. mapp[i][j - flag] = mapp[i][j];
  75. mapp[i][j] = 0;
  76. }
  77. }
  78. }
  79. }
  80. //交换操作
  81. il void move(int i,int j,int flag)
  82. {
  83. swap(mapp[i][j],mapp[i+flag][j]);
  84. update();
  85. while(reover()) update();
  86. }
  87. //搜索
  88. void dfs(int x)
  89. {
  90. if(gameover())
  91. {
  92. for(int i = 1;i <= n;++i)
  93. {
  94. if(i != 1) cout << endl;
  95. cout << ans[i][1] <<" "<< ans[i][2] <<" "<< ans[i][3];
  96. }
  97. exit(0);
  98. }
  99. if(x == n+1) return;
  100. copy(x);
  101. for(int i = 1;i <= 5;++i)
  102. for(int j = 1;j <= 7;++j)
  103. {
  104. if(mapp[i][j])
  105. {
  106. if(i-1 >= 1 && mapp[i-1][j] == 0)
  107. {
  108. move(i,j,-1);
  109. ans[x][1] = i-1;
  110. ans[x][2] = j-1;
  111. ans[x][3] = -1;
  112. dfs(x+1);
  113. for(int i = 1;i <= 5;++i)
  114. for(int j = 1;j <= 7;++j)
  115. mapp[i][j] = last[x][i][j];
  116. ans[x][1] = 0;
  117. ans[x][2] = 0;
  118. ans[x][3] = 0;
  119. }
  120. if(i+1 <= 5 && mapp[i][j] != mapp[i+1][j])
  121. {
  122. move(i,j,1);
  123. ans[x][1] = i-1;
  124. ans[x][2] = j-1;
  125. ans[x][3] = 1;
  126. dfs(x+1);
  127. for(int i = 1;i <= 5;++i)
  128. for(int j = 1;j <= 7;++j)
  129. mapp[i][j] = last[x][i][j];
  130. ans[x][1] = 0;
  131. ans[x][2] = 0;
  132. ans[x][3] = 0;
  133. }
  134. }
  135. }
  136. }
  137. int main(int argc, char const *argv[])
  138. {
  139. n = read();
  140. for(int i = 1;i <= 5;++i)
  141. for(int j = 1;j <= 8;++j)
  142. {
  143. int x = read();
  144. if(x == 0) break;
  145. mapp[i][j] = x;
  146. }
  147. dfs(1);
  148. printf("-1\n");
  149. return 0;
  150. }

例3 P1120 小木棍

题目描述

乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50。

现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。

给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度。

输入输出格式

输入格式:

共二行。

第一行为一个单独的整数N表示砍过以后的小木棍的总数,其中N≤65

(管理员注:要把超过50的长度自觉过滤掉,坑了很多人了!)

第二行为N个用空个隔开的正整数,表示N根小木棍的长度。

输出格式:

一个数,表示要求的原始木棍的最小可能长度

输入输出样例

输入样例#1: 复制

  1. 9
  2. 5 2 1 5 2 1 5 2 1

输出样例#1: 复制

  1. 6

说明

2017/08/05

数据时限修改:

-#17 #20 #22 #27 四组数据时限500ms

-#21 #24 #28 #29 #30五组数据时限1000ms

其他时限改为200ms(请放心食用)

标程

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxx = 66;
  4. int n,maxn = -maxx,minn = maxx;
  5. int tong[maxx];
  6. void dfs( int res , int sum , int target , int p ) {
  7. if( res == 0 ) {
  8. printf("%d", target );
  9. exit( 0 );
  10. }
  11. if( sum == target ) {
  12. dfs( res - 1 , 0 , target , maxn );
  13. return;
  14. }
  15. for( int i = p ; i >= minn ; i -- ) {
  16. if( tong[ i ] && i + sum <= target ) {
  17. tong[ i ] -- ;
  18. dfs( res , sum + i , target , i );
  19. tong[ i ] ++ ;
  20. if ( sum == 0 || sum + i == target )
  21. break;
  22. }
  23. }
  24. return;
  25. }
  26. int main(int argc, char const *argv[])
  27. {
  28. scanf("%d",&n);
  29. int x,cnt = 0,sum;
  30. while(n--)
  31. {
  32. scanf("%d",&x);
  33. if(x <= 50)
  34. {
  35. cnt++;
  36. tong[x]++;
  37. sum += x;
  38. maxn = max(maxn,x);
  39. minn = min(minn,x);
  40. }
  41. }
  42. x = sum/2;
  43. for(int i = maxn;i <= x;i++)
  44. {
  45. if(sum%i == 0)
  46. {
  47. dfs(sum/i,0,i,maxn);
  48. }
  49. }
  50. printf("%d",sum);
  51. return 0;
  52. }

NOIP2018考前抱佛脚——搜索复习的更多相关文章

  1. NOIP2018考前抱佛脚——图论基础复习

    目录 存图方式 邻接矩阵存图 邻接表存图 链式前向星 最小生成树 例1 P1536 村村通 题目描述 输入输出格式 输入输出样例 标程 例2 P1546 最短网络 Agri-Net 题目背景 题目描述 ...

  2. NOIP2018考前抱佛脚——数据结构基础及STL实现

    目录 动态数组 栈 队列 优先队列 动态数组 srand(time(0)); std::vector<int> qwq; for(int i = 1;i <= 10;++i) qwq ...

  3. 【Spark】【复习】Spark入门考前概念相关题复习

    Spark考前概念相关题复习 AUthor:萌狼蓝天 哔哩哔哩:萌狼蓝天 博客园:我的文章 - 萌狼蓝天 博客:萌狼工作室 - 萌狼蓝天 (mllt.cc) 选择题 Hadoop 1.HADOOP的三 ...

  4. Noip2018 考前准备

    目录 基础算法 二分 模拟(未补) 高精(未学习) 搜索(未补) 排序 图论 树的直径 树的重心 最短路算法 Spfa Dijkstra Floyd 最小生成树 kruskal 数论 线性筛 线性筛素 ...

  5. NOIP2018初赛提高组复习提纲(By HGOI LJC)

    Download:https://pan.baidu.com/s/16khhFf_0RsUjJLETreb20w (PDF) https://pan.baidu.com/s/1BVZqLs3q1clZ ...

  6. noip考前抱佛脚 数论小总结

    exCRT 求解韩信点兵问题,常见的就是合并不同\(mod\). 先mo一发高神的板子 for(R i=2;i<=n;++i){ ll Y1,Yi,lcm=Lcm(p[i],p[1]); exg ...

  7. noip2018 考前提醒!

    适应Noilinux 1.终端操作 打开终端 \(Ctrl+Alt+T\) 打开文件夹 \(cd\) +名称 新建文件夹 \(mkdir\) +名称 打开 \(vim\) 配置 \(vim ~/.vi ...

  8. Noip2018退役记。

    下面是边考试边写的严肃版退役记\(:D\) Day0 其实我本来想取个这个名字:\(NOIP2018\)提高组复赛试题解析 但是这个博客自己求生欲望太强自己改名了. 先占个坑. noip考前毒奶 \( ...

  9. A - Oil Deposits(搜索)

    搜索都不熟练,所以把以前写的一道搜索复习下,然后下一步整理搜索和图论和不互质的中国剩余定理的题 Description GeoSurvComp地质调查公司负责探测地下石油储藏. GeoSurvComp ...

随机推荐

  1. 七台机器部署Hadoop2.6.5高可用集群

    1.HA架构注意事项 两个Namenode节点在某个时间只能有一个节点正常响应客户端请求,响应请求的节点状态必须是active standby状态要能够快速无缝切换成active状态,两个NN节点必须 ...

  2. WPF 中Canvas图形移动、缩放代码

    从Flash转C#,很多内容一知半解,边摸索边前进,代码粗糙,权当留个脚印. 只是想得到一个基础的移动和缩放功能的界面,找了很久都是画线.画矩形等基础形状的代码,移动和缩放说的并不清晰,只能自己努力来 ...

  3. Java基础——可变参数

    大家都知道main方法的参数就是一个数组类型的,那么它其实也是可以改成不定参数类型.我试了试,并调用了一些弹出来的方法. public class ClassC2 { public static vo ...

  4. sql语句之where子句

    现在的登录都是把信息存在数据库,然后把输入的与数据库内容进行匹配,一样就登录成功,否则不成功.验证码是为了防止暴力破解,因为计算机能够自动匹配密码,但是不能识别图片上的字母,只有人能识别,所以匹配的速 ...

  5. js多线程(worker)

    浏览器端js是单线程执行,所以当js执行高负载运算时,UI渲染就会阻塞,页面就会出现卡顿,用户体验就不是很好 js为此也提供了异步操作,例如: 定时器(setTimeout 和 setInterval ...

  6. AngularJS简单入门

    什么是AngularJS AngularJS是一款优秀的前端JS框架,是Google多款产品之一,简称ng. ng有着诸多特性,最为核心的是:MVVM.模块化.自动化双向数据绑定.语义化标签.依赖注入 ...

  7. LeetCode题解之 Convert Sorted Array to Binary Search Tree

    1.题目描述 2.问题分析 使用二分法即可. 3.代码 TreeNode* sortedArrayToBST(vector<int>& nums) { ) return NULL; ...

  8. LeetCode题解之Find All Duplicates in an Array

    1.题目描述 2.问题分析 将数组中的元素 A[i] 放到 A[ A[i] - 1] 的位置.然后遍历一边数组,如果不满足 A[i] == i+1,则将A[i]添加到 结果中. 3.代码 vector ...

  9. 七牛云A账号数据迁移到B账号下

    1,七牛云A账号下开启空间授权,可以让B账号可以访问A账号下的空间,,授予权限只读即可. 2,下载七牛云命令行工具.(通过命令完成数据迁移) https://dn-devtools.qbox.me/2 ...

  10. Error Fix – Replication subscriber does not exist on the server anymore(删除Replication时报错的解决办法)

    Recently one of my client has faced weird situation related to SQL Server Replication. Their main da ...