1.25所有题总结
车厢调度的两种方法:1.依次判断是否是上个元素-1或比上个元素大,若不是则输出no
2.寻找不一定连续的(大,中,小)结构。
#include<bits/stdc++.h> #define enter printf("\n") #define n_times_a scanf("%d",&n);for(int i = 1;i <= n;i++){scanf("%d",&a[i]);} using namespace std; int main(){ int n,a[200] = {},b[200]; int top = 1,f = 1; scanf("%d",&n); for(int i = 1;i <= n;i++){ scanf("%d",&a[i]); } for(int i = 1;i <= n;i++){ //way#1 /*//printf("%d , %d\n",a[i],top - 1); if(a[i] < top - 1){ f = 0; break; } else top = a[i];*/ //way#2 // /* if(a[i] == b[top]){ b[top--] = 0; continue; //若为当前栈顶元素,则出栈 } for(int j = 1;j < top;j++){ if(a[i] = b[j]){ printf("NO"); exit(0); } } for(int j = i==0?1:a[i-1]+1;j < a[i];j++){ b[top++] = j; } // */ } /*if(f)*/ printf("YES"); //else printf("NO"); return 0; }
用进出栈来模拟进出站
2.迷宫问题
比较有进步的是学会了用数组记录行动规则,同时根据行动的显性+隐性规则进行模拟!
隐藏规则:不能原地不动,不能越界
题中注释较为详细
#include<bits/stdc++.h> using namespace std; int n,tot,a[10][10]; //地图 int stp[3] = {-1,0,1}; int r[10][10]; //路线图 void step(int x,int y){ //printf("%d %d\n",y,x); if(y == 1 && x == n){ //printf("ok\n"); tot++; return; } for(int i = 0;i <= 2;i++){ for(int j = 0;j <= 2;j++){ if(stp[i] == 0 && stp[j] == 0) continue; //不能原地不动 if(x+stp[i] > n||y+stp[j] > n||x+stp[i] < 1||y+stp[j] < 1) continue; //不能越界 if(a[y+stp[j]][x+stp[i]] == 1) continue; //不能进入不可通过区域 if(r[y+stp[j]][x+stp[i]] == 1) continue; //路线不能重复 r[y+stp[j]][x+stp[i]] = 1; step(x+stp[i],y+stp[j]); r[y+stp[j]][x+stp[i]] = 0; } } } void input(){ for(int i = 1;i <= n;i++){ for(int j = 1;j <= n;j++){ scanf("%d",&a[i][j]); } } } int main(){ scanf("%d",&n); input(); r[1][1] = 1; step(1,1); printf("%d",tot); return 0; } /* 3 0 0 0 0 1 1 1 0 0 */
3.部落卫队问题
一道意料之外卡了很久的题,一开始的算法有漏洞:回溯的时候保持回溯前的仇敌状态,这个需要加减实现而不是0,1的区别!
同时判断过程复杂也使得思维紊乱,后面我都改成了函数形式
#include<bits/stdc++.h> using namespace std; int n,m,ans = 0,a[200]; int h[200][200]; //h表示仇敌关系, h[k][j]表示 k第j仇敌编号 int op[200]; //记录选入的成员编号 int b[200]; //0表示可选,1以上表示不可选 int c[200]; void ck(int t){ if(t > ans){ ans = t; for(int i = 1;i <= n;i++){ op[i] = a[i]; } } } void ene(int i){ int j = 1; while(h[i][j]){ b[h[i][j]]++; j++; } b[i]++; } void abene(int i){ int j = 1; while(h[i][j]){ b[h[i][j]]--; j++; } b[i]--; } void prt(int t){ printf("%d\n",t); for(int i = 1;i <= n;i++){ printf("%d ",a[i]); } printf("\n"); } void search(int t,int d){ //当前选入第几个人 ,从谁开始选 for(int i = d;i <= n;i++){ if(!b[i]){ //如果可选 ene(i); a[i] = 1; ck(t); //prt(t); search(t+1,i+1); a[i] = 0; abene(i); } } } void print(){ //printf("answer:\n"); printf("%d\n",ans); for(int i = 1;i <= n;i++){ printf("%d ",op[i]); } } int main(){ int k,x; scanf("%d%d",&n,&m); for(int i = 1;i <= m;i++){ scanf("%d %d",&k,&x); int l = 1; while(h[k][l] > 0) l++; h[k][l] = x; } search(1,1); print(); return 0; } /* 7 10 1 2 1 4 2 4 2 3 2 5 2 6 3 5 3 6 4 5 5 6 */
4.最佳调度问题
题解似乎也过不了的一道题,时间复杂度还是要继续优化,
(以下是当前优化到的状态,还不知要试多久)
#include<bits/stdc++.h> using namespace std; int mint,a[30],n,k; int t[20]; //t[i]是第i个机器用时 void dfs(int y,int r){ //已安排的任务数 最短用时(排序) if(r >= mint){ return; } if(y > n){ if(r < mint) mint = r; return; } for(int i = 1;i <= k;i++){ t[i] = a[y]+t[i]; dfs(y+1,max(r,t[i])); t[i] = t[i]-a[y]; } } int main(){ scanf("%d %d",&n,&k); for(int i = 1;i <= n;i++){ scanf("%d",&a[i]); } mint = INT_MAX; dfs(1,0); printf("%d",mint); } //7 3 2 14 4 16 6 5 3
5.m着色问题
此题涉及知识盲区,纸上瞎写一通,看完题解也是一脸问号,目前只知道数组记录互相影响节点的算法
#include<bits/stdc++.h> #define i i using namespace std; int n,m,k,e[10000],t[10000],a[10000]; int color[10000],tot; void dfs(int x){ //着色点个数 if(x > n){ tot++; return; } int i; bool b[1000] = {}; i = color[x]; while(i!=0){ if(e[i]<x) b[a[e[i]]] = false; i = next[i]; } for(int i = 1;i < k;i++){ if(b[i]){ a[x] = i; dfs(x+1); } } } int main(){ cin>>n>>k>>m; int x,y; for(int i = 1;i <= k;i++){ cin>>x>>y; if(x>y) swap(x,y); t[i] = e[x];t[i+k] = e[y]; color[x] = i;color[y] = i+k; e[i] = y;e[i+k] = x; } tot = 0; dfs(1); cout<<tot<<endl; }
浙公网安备 33010602011771号