搜索
目录:
P1036 [NOIP2002 普及组] 选数
P2392 kkksc03考前临时抱佛脚
P1025 [NOIP2001 提高组] 数的划分
P6201 [USACO07OPEN]Fliptile S
P1460 [USACO2.1]健康的荷斯坦奶牛 Healthy Holsteins
P1135 奇怪的电梯
P1763 埃及分数
PS:图的遍历用BFS和DFS搜索
- //bfs
- #include<iostream>
- #include<queue>
- using namespace std;
- queue<int>q;
- //使用邻接矩阵的BFS
- void BFS(int u)
- {
- vis[u] = true;
- q.push(u);
- while(!q.empty())
- {
- int head = q.front();
- q.pop();
- for(int w = 1;w <= n;w++){
- if(edge[v][w] && !vis[w]){
- vis[w] = true;
- q.push(w);
- }
- }
- }
- }
-
-
- //用栈来实现
- void dfs(int u)
- {
- vis[u] = 1;
- for(int i = 1;i <= n;i++)
- {
- if(edge[u][i] && !vis[v]) dfs(i);
- }
- }
- int main()
- {
-
- return 0;
- }
实力直接回炉重造!!!
我花了三小时调试这题,没想到,败在括号上!!!
- #include
- using namespace std;
- const int N = 30;
- int a[N];
- int n,k;
- int ans;
- bool is_prime(int x)
- {
- for(int i = 2;i * i <= x;i++)
- if(x % i == 0)return false;
- return true;
- }
-
- void dfs(int m,int sum,int sta)
- {
- if(m == k)
- {
- if(is_prime(sum)) ans++;
- return;
- }
-
- for(int i = sta;i < n;i++)
- dfs(m+1,sum+a[i],i+1);
- return;
- }
- int main()
- {
- cin>>n>>k;
-
- for(int i = 0;i < n;i++)
- cin>>a[i];
-
- dfs(0,0,0);
- cout<
-
-
- return 0;
- }
P2392 kkksc03考前临时抱佛脚
思路:枚举左右脑分别工作即可
- #include
- using namespace std;
- int a[5],b[5][36];//表示a[N]哪一科,而b[ ][ ]表示一科中有多少道题
- int minn = -0x3f3f3f3f;
- int ans;
- int l,r;
- void dfs(int p,int n)//p表示几道题
- {
- if(p > a[n])
- {
- minn = min(max(l,r),minn);
- return;
- }
- l += b[n][p];
- dfs(p+1,n);
- l -= b[n][p];
-
- r += b[n][p];
- dfs(p+1,n);
- r -= b[n][p];
- }
- int main()
- {
- for(int i = 1;i <= 4;i++)
- {
- cin>>a[i];
- }
- for(int i = 1;i <= 4;i++)
- {
- for(int j = 1;j <= a[i];j++)
- {
- cin>>b[i][j];
- }
- l = 0,r = 0;//两个头脑都还没开始工作
- minn = 0x3f3f3f3f;
- dfs(1,i);
- ans += minn;
-
- }
- cout<
- return 0;
- }
P1025 [NOIP2001 提高组] 数的划分
思路:
记录上一次划分所用的数,保证当前划分所用数不小于上次划分所用分数,当划分次数等于k时比较该次划分所得总分是否与n相同并记录次数。
- #include
- using namespace std;
- int n,k;
- int cnt;
- void dfs(int m,int sum,int sta)//m为上一次所划分的数,sum表示所得总份数,sta表示划分数中剩余的次数
- {
- //处理分完的部分
- if(sta == k)
- {
- if(sum == n)
- cnt++;
- return;
- }
-
- for(int i = m;i <= n-sum;i++)//剪枝部分
- dfs(i,sum+i,sta+1);
- return;
- }
- int main()
- {
- cin>>n>>k;
- dfs(1,0,0);
- cout<
- return 0;
- }
P6201 [USACO07OPEN]Fliptile S
思路:
因为对于第i行(i>=2)的数字只取决于它正上方的数字(mp[i-1][j])是1还是0,因为这是mp[i-1][j]最后的一次修改机会,我们必须把它更改成0。
如果mp[i-1][j]=1,这个格子就必须要翻,如果mp[i-1][j]=0,这个格子就一定不能翻。当所有的数都按照规则翻完后,如果图内没有1存在则合法,否则return
枚举第一行的即可!
- #include
- using namespace std;
- const int INF = 20000007;
- const int N = 30;
- int a[N][N];
- //因为对于第i行(i>=2)的数字只取决于它正上方的数字(a[i-1][j])是1还是0,因为这是a[i-1][j]最后的一次修改机会,我们必须把它更改成0.
- //如果a[i-1][j]=1,这个格子就必须要翻,如果a[i-1][j]=0,这个格子就一定不能翻。
- int n,m;
- int ans[N][N],p[N][N],q[N][N];
- int mxn = INF;
- void dfs(int x)
- {
- if(x > m)
- {
- for(int i = 1;i <= n;i++)
- for(int j = 1;j <= m;j++)
- p[i][j] = q[i][j];
-
- for(int i = 1;i <= m;i++)
- if(a[1][i])
- {
- p[1][i] ^= 1,p[2][i] ^= 1;
- p[1][i+1] ^= 1,p[1][i-1] ^= 1;
- }
-
- for(int i = 2;i <= n;i++)
- for(int j = 1;j <= m;j++)
- {
- //重点来了!!!
- if(p[i-1][j] == 1)
- {
- a[i][j] = 1;
- p[i][j] ^= 1;
- p[i][j+1] ^= 1;
- p[i][j-1] ^= 1;
- p[i+1][j] ^= 1;
- p[i-1][j] ^= 1;
- //四方位全翻一次
- }
- else a[i][j] = 0;
- if(p[i-1][j])return;
- }
-
- bool flag = false;
- for(int i = 1;i <= n;i++)
- for(int j = 1;j <= m;j++)
- if(p[i][j])
- {
- flag = true;
- break;
- }
- if(!flag)
- {
- int tot = 0;
- for(int i = 1;i <= n;i++)
- for(int j = 1;j <= m;j++)
- if(a[i][j])tot++;
-
- if(tot >= mxn)return;
- mxn = tot;
-
- for(int i = 1;i <= n;i++)
- for(int j = 1;j <= m;j++)
- ans[i][j] = a[i][j];
- }
- return;
- }
- for(int i = 0;i <= 1;i++)
- {
- a[1][x] = i;
- dfs(x+1);
- }
- }
- int main()
- {
- cin>>n>>m;
- for(int i = 1;i <= n;i++)
- for(int j = 1;j <= m;j++)
- cin>>q[i][j];
- dfs(1);
-
- if(mxn == INF)cout<<"IMPOSSIBLE";
- else
- {
- for(int i = 1;i <= n;i++)
- {
- for(int j = 1;j < m;j++)
- cout<
" "; - cout<
- }
- }
- return 0;
- }
P1460 [USACO2.1]健康的荷斯坦奶牛 Healthy Holsteins
P1460 [USACO2.1]健康的荷斯坦奶牛 Healthy Holsteins - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
- #include
- using namespace std;
- const int N = 30;
- int a[N],sl[N][N];//表示维他命的数量
- int v,g;
- int minn = 0x3f3f3f3f;
- int cur[N];//表示当时枚举的子集选中了哪些饲料
- int ans[N];//表示全局选中的哪些饲料
- bool check(int x)
- {
- for(int i = 1;i <= v;i++)
- {
- int sum = 0;
- for(int j = 1;j <= x;j++)
- {
- sum+=sl[cur[j]][i];
- }
- if(sum < a[i])
- {
- return false;
- }
- }
- return true;
- }
- void dfs(int dq,int cnt)//dq当前枚举的饲料编号,cnt表示当前子集元素的总个数
- {
- if(dq == g+1)
- {
- if(check(cnt) == true)
- {
- if(minn > cnt)
- {
- minn = cnt;
- for(int i = 1;i <= cnt;i++)
- {
- ans[i] = cur[i];
- }
- }
- }
- return;
- }
- if(dq <= g)
- {
- cur[cnt+1] = dq;
- //选中
- dfs(dq+1,cnt+1);
- //不选
- dfs(dq+1,cnt);
- cur[cnt+1] = 0;
- }
-
-
- }
- int main()
- {
- cin>>v;
- for(int i = 1;i <= v;i++)
- {
- cin>>a[i];
- }
- cin>>g;
- for(int i = 1;i <= g;i++)
- {
- for(int j = 1;j <= v;j++)
- {
- cin>>sl[i][j];
- }
- }
- dfs(1,0);
- cout<
" "; - for(int i = 1;i <= minn;i++)
- {
- cout<
" "; - }
- cout<
-
- return 0;
- }
P1135 奇怪的电梯
思路:直接dfs爆搜一边即可
我自己都服了,我会犯低级错误
没判断按键的数量是否会超过预期数量
- //P1135 奇怪的电梯
- //直接 dfs往下搜即可
- //也可以转化为图的模式
- #include
- using namespace std;
- const int N = 220;
- int a,b,n;
- int K[N];
- int cnt = 0x3f3f3f3f;
- bool vis[N];
- void dfs(int m,int sum)//m表示当前搜到的楼层,sum表示按钮次数
- {
- if(m == b) cnt = min(cnt,sum);
- return;
- vis[m] = 1;
- //不越界就搜
- if(m+K[m] <= n && !vis[m+K[m]]) dfs(m+K[m],sum+1);
- if(m-K[m] >= 1 && !vis[m-K[m]]) dfs(m-K[m],sum+1);
-
- vis[m] = 0;
- return;
- }
- int main()
- {
- ios::sync_with_stdio(false);
- cin.tie(0);
- cin>>n>>a>>b;
- for(int i = 1;i <= n;i++)
- {
- cin>>K[i];
- }
-
- vis[a] = 1;
- dfs(a,0);
-
- if(cnt != 0x3f3f3f3f) cout<
- else cout<<"-1"<
-
- return 0;
- }
P1763 埃及分数
没开ll的后果!!!
警钟长鸣!!
- #include
- using namespace std;
- #define ll long long
- const int N = 1e8+10;
- ll sum[N];
- ll a[N];
- int ans;
- bool dfs(ll mol,ll x,ll y)
- {
- if(mol == ans + 1)
- {
- if(x != 0)
- {
- return false;
- }
- if(sum[ans] > a[ans])
- {
- for(int i = 1;i <= ans;i++)
- {
- sum[i] = a[i];
- }
- }
- return true;
- }
- bool flag = false;
-
- for(ll i = max((ll)(ceil(y/x)),a[mol-1]+1);i <= ceil(y/x) * (ans - mol + 1);i++)//枚举分母
- {
- a[mol] = i;
- ll dx = x * i - y;
- ll dy = y * i;
- ll g = __gcd(dx,dy);
- dx /= g;
- dy /= g;
- if(dfs(mol+1,dx,dy))
- {
- flag = true;
- }
- }
- return flag;
- }
- ll x,y;
- int main()
- {
- scanf("%lld %lld",&x,&y);
- for(ans = 1;;ans++)
- {
- sum[ans] = 0x3f3f3f3f;
- if(dfs(1,x,y) == true)//搜到的每一个加数
- {
- break;
- }
- }
-
- for(int i = 1;i <= ans;i++)
- {
- printf("%lld ",sum[i]);
- }
- return 0;
- }
-
相关阅读:
C++ 多态
golang协程原理
力扣第38天----第139题
ModuleNotFoundError: No module named ‘unstructured‘
数学建模__动态规划
GoLand远程开发IDE:使用SSH远程连接服务器进行云端编程
[附源码]计算机毕业设计springboot校园疫情防范管理系统
CC2530中文数据手册
CSAPP Lab6:Malloc
【C++】设计模式之单例模式
-
原文地址:https://blog.csdn.net/Demilly123/article/details/127087185