冲刺省选习题集
1.火柴棒等式
? ?單擊此處看題目
考察算法:數學分析+枚舉
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 5 const int match[10]={6,2,5,5,4,5,6,3,7,6}; 6 7 int n; 8 9 int merge(int x){ 10 int sum=0; 11 if(x==0)return 6; 12 while(x){ 13 sum+=match[x%10]; 14 x/=10; 15 } 16 return sum; 17 } 18 19 int main(){ 20 freopen("matches.in","r",stdin); 21 freopen("matches.out","w",stdout); 22 scanf("%d",&n); 23 int a,b,c,res=0; 24 n-=4; 25 for(a=0;a<=1000;a++) 26 for(b=0;b<=1000;b++) 27 { 28 c=a+b; 29 if(n==(merge(a)+merge(b)+merge(c))) 30 res++; 31 } 32 printf("%d",res); 33 return 0; 34 }2.作業調度方案
? ? ?單擊此處看題目
考察算法:語文分析+模擬+離散化
具體做法:將工件的工序離散到機器的時間軸,然后尋找插入即可
1 #include <iostream> 2 #include <cstdio> 3 #include <queue> 4 #include <cstring> 5 using namespace std; 6 7 const int MaxN=21; 8 9 int n,m,cost[MaxN][MaxN]; 10 int machen[MaxN][MaxN]; 11 int d[MaxN*MaxN]; 12 int num[MaxN]; 13 bool ok[MaxN][MaxN*MaxN]; 14 int f[MaxN][MaxN]; 15 16 void readfile(){ 17 freopen("jsp.in","r",stdin); 18 freopen("jsp.out","w",stdout); 19 scanf("%d%d",&m,&n);//m個機器,n個工件數,m道工序 20 int i,j,x; 21 for(i=1;i<=m*n;i++)scanf("%d",&d[i]); 22 for(i=1;i<=n;i++) 23 for(j=1;j<=m;j++) 24 scanf("%d",&machen[i][j]);//第i個工件第j道工序應放入的機器號machen[i][j] 25 for(i=1;i<=n;i++) 26 for(j=1;j<=m;j++) 27 scanf("%d",&cost[i][j]);//第i件工件第j道工序花費的時間 28 } 29 30 void work(){ 31 int i,j,k,p,sss,ans=0; 32 bool flag=false; 33 memset(ok,false,sizeof(ok)); 34 for(i=1;i<=m*n;i++) 35 { 36 k=machen[d[i]][++num[d[i]]];//按照順序第i件工件所應該放的機器號 37 p=f[d[i]][num[d[i]]-1]; 38 while(1){ 39 flag=false; 40 sss=p; 41 for(j=0;j<cost[d[i]][num[d[i]]];j++) 42 if(ok[k][p++]==true){ 43 flag=true; 44 break; 45 } 46 if(flag==false)break; 47 } 48 for(j=0;j<cost[d[i]][num[d[i]]];j++) 49 ok[k][sss+j]=true; 50 f[d[i]][num[d[i]]]=p; 51 ans=max(ans,p); 52 } 53 cout<<ans; 54 } 55 56 int main(){ 57 readfile(); 58 work(); 59 return 0; 60 }3.引水入城
??單擊此處看題目
考察算法:廣度優先搜索染色(FLOOD_FILL)+貪心
具體做法:首先利用BFS求出p數組和g數組(作用程序段中會給出),然后我們掃描p數組如果len=0則證明沒有城市可以流入,累計下來輸出0,否則用貪心的思想,累計每個蓄水廠可以流到的線段的左端點和右端點,然后求下一個,以此類推,時間復雜度O(NM)
1 #include <iostream> 2 #include <cstdio> 3 #include <queue> 4 #include <cstring> 5 using namespace std; 6 7 const int MaxN=501; 8 9 struct element{ 10 int L,R;//表示該點能流入的左端點和右端點 11 element(){L=1<<30;R=0;} 12 }g[MaxN]; 13 14 struct xOy{ 15 int X,Y; 16 }; 17 18 int n,m,height[MaxN][MaxN]; 19 int p[MaxN][MaxN],len[MaxN];//流入第n行第i列的城市的編號 20 bool vis[MaxN][MaxN]; 21 22 void bfs(int x,int y){ 23 queue<xOy> q; 24 int headx,heady; 25 memset(vis,false,sizeof(vis)); 26 q.push((struct xOy){x,y}); 27 vis[x][y]=true; 28 while(!q.empty()){ 29 headx=q.front().X; 30 heady=q.front().Y; 31 q.pop(); 32 if(headx==n){ 33 p[heady][++len[heady]]=y; 34 g[y].L=min(g[y].L,heady); 35 g[y].R=max(g[y].R,heady); 36 } 37 if(headx-1>0 && vis[headx-1][heady]==false && height[headx][heady]>height[headx-1][heady]) 38 { 39 q.push((struct xOy){headx-1,heady}); 40 vis[headx-1][heady]=true; 41 } 42 if(headx+1<=n && vis[headx+1][heady]==false && height[headx][heady]>height[headx+1][heady]) 43 { 44 q.push((struct xOy){headx+1,heady}); 45 vis[headx+1][heady]=true; 46 } 47 if(heady-1>0 && vis[headx][heady-1]==false && height[headx][heady]>height[headx][heady-1]) 48 { 49 q.push((struct xOy){headx,heady-1}); 50 vis[headx][heady-1]=true; 51 } 52 if(heady+1<=m && vis[headx][heady+1]==false && height[headx][heady]>height[headx][heady+1]) 53 { 54 q.push((struct xOy){headx,heady+1}); 55 vis[headx][heady+1]=true; 56 } 57 } 58 } 59 60 int main(){ 61 freopen("flow.in","r",stdin); 62 freopen("flow.out","w",stdout); 63 scanf("%d%d",&n,&m); 64 int i,j,tot=0,MAX=0; 65 for(i=1;i<=n;i++) 66 for(j=1;j<=m;j++) 67 scanf("%d",&height[i][j]); 68 for(i=1;i<=m;i++)bfs(1,i); 69 for(i=1;i<=m;i++) 70 if(len[i]==0)tot++; 71 if(tot>0){ 72 printf("0\n%d",tot); 73 return 0; 74 } 75 for(i=1;i<=m;) 76 { 77 MAX=0; 78 for(j=1;j<=len[i];j++)//貪心的尋找一個最優位置 79 if(g[p[i][j]].R>MAX) 80 MAX=g[p[i][j]].R; 81 i=MAX+1; 82 tot++; 83 } 84 printf("1\n%d",tot); 85 return 0; 86 }4.國王游戲
??單擊此處看題目
? 考察算法:貪心+高精度(高除單+高乘單)
? 具體操作:按左右手乘積從小到大排序
1 //挖掘機技術哪家強?中國山東找藍翔 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <cmath> 6 #include <cstring> 7 #include <algorithm> 8 #include <string> 9 using namespace std; 10 11 const int MaxN=1000001; 12 const int Max_Size=1000001; 13 const int mod=10000;//萬進制 14 15 struct person{ 16 int Left,Right; 17 friend bool operator< (person c,person b){ 18 return c.Left*c.Right<b.Left*b.Right;//greedy 19 } 20 }a[MaxN]; 21 22 int n; 23 int Now[Max_Size],l1; 24 int hav[Max_Size],l;//當前大臣所能獲得的錢 25 int best[Max_Size],lb;//最多的錢 26 27 void init(){ 28 freopen("game.in","r",stdin); 29 freopen("game.out","w",stdout); 30 scanf("%d",&n); 31 int i; 32 scanf("%d%d",&a[0].Left,&a[0].Right);//國王 33 for(i=1;i<=n;i++)scanf("%d%d",&a[i].Left,&a[i].Right); 34 } 35 36 int comp(int a[],int b[]){ 37 int i; 38 if(l>lb)return 1; 39 else if(l<lb)return 0; 40 for(i=1;i<=lb;i++) 41 if(a[i]>b[i])return 1; 42 else if(a[i]<b[i])return 0; 43 return 0; 44 } 45 46 void change(){ 47 int i; 48 lb=l; 49 for(i=1;i<=l;i++)best[i]=hav[i]; 50 } 51 52 void greedy(){ 53 sort(a+1,a+n+1);//按照左右手乘積從小到大排序 54 int i,j,tmp=0,k=0; 55 Now[l1=1]=1;//初始化當前值 56 for(i=1;i<=n;i++){ 57 for(j=1;j<=l1;j++){ 58 tmp=Now[j]*a[i-1].Left+k; 59 Now[j]=tmp%mod; 60 k=tmp/mod; 61 } 62 while(k>0){ 63 Now[++l1]=k%mod; 64 k/=mod; 65 } 66 tmp=l=0; 67 for(j=l1;j>=1;j--){ 68 hav[++l]=(tmp*mod+Now[j])/a[i].Right; 69 tmp=(tmp*mod+Now[j])%a[i].Right; 70 } 71 if(comp(hav,best)==1)change(); 72 } 73 int front=1; 74 while(best[front]==0)front++; 75 printf("%d",best[front]); 76 for(i=front+1;i<=lb;i++)printf("%4.4d",best[i]); 77 } 78 79 int main(){ 80 init(); 81 greedy(); 82 return 0; 83 }5.2^k進制數
6.聰明的質檢員
? 單擊此處看題目
? 考察算法:分治(二分答案)+線型DP+二次函數分析
? 具體操作:二分W,然后利用二次函數得出W和Y成反比例,所以用函數來計算Y,如果過大則增大W,反之同理
? 時間復雜度O(NMlogWmax)
? 優化:通過DP的前綴和手段,O(1)時間查找該區間滿足條件的價值總和和個數
? 代碼有注釋
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 using namespace std; 6 7 const int MaxN=200001; 8 9 struct segment{ 10 int l,r; 11 }a[MaxN]; 12 13 int n,m; 14 long long s,Y; 15 int w[MaxN],v[MaxN]; 16 17 void init(){ 18 freopen("qp.in","r",stdin); 19 freopen("qp.out","w",stdout); 20 cin>>n>>m>>s; 21 int i; 22 for(i=1;i<=n;i++)scanf("%d%d",&w[i],&v[i]); 23 for(i=1;i<=m;i++)scanf("%d%d",&a[i].l,&a[i].r); 24 } 25 26 int f[MaxN];//前i個礦石質量大于等于W的個數 27 long long g[MaxN];//前i個質量大于等于W的礦石總價值 28 29 void check(int W){ 30 int i; 31 Y=0; 32 memset(f,0,sizeof(f)); 33 memset(g,0,sizeof(g)); 34 for(i=1;i<=n;i++)//初始化g和f數組 35 { 36 f[i]=f[i-1]; 37 g[i]=g[i-1]; 38 if(w[i]>=W){ 39 f[i]=f[i-1]+1; 40 g[i]=g[i-1]+v[i]; 41 } 42 } 43 for(i=1;i<=m;i++) 44 Y+=(f[a[i].r]-f[a[i].l-1])*(g[a[i].r]-g[a[i].l-1]); 45 } 46 47 void solve(){ 48 int low=1,high=0,mid; 49 int i; 50 long long ans=1LL<<60; 51 for(i=1;i<=n;i++)//以最大質量為最大值 52 if(w[i]>high) 53 high=w[i]; 54 while(low<=high){ 55 mid=(low+high)>>1;//二分答案 56 check(mid); 57 if(abs(Y-s)<ans)ans=abs(Y-s); 58 if(Y>s)low=mid+1; 59 else high=mid-1; 60 } 61 cout<<ans; 62 } 63 64 int main(){ 65 init(); 66 solve(); 67 return 0; 68 }7.斐波那契數列
8.Hankson的趣味題
9.同余方程
? 單擊此處看題目
? 考察算法:拓展歐幾里得+數學變換
? 題目要求解ax=1 (mod b)
? 顯然有ax=by+1 (y (- Z)
? 那么轉變得ax-by=1
? 此時我們可以假想為求2元一次不定方程的最小解
? 使用拓展歐幾里得來解決
? 但是注意,這里不是ax+by=1,所以x需要消除符號,即多次求模即可
? x=(x%b+b)%b
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 5 int a,b; 6 /* ax=1(mod b) 7 ax=by+1 8 ax-by=1 9 ax+(-by)=1 10 */ 11 12 int exgcd(int a,int b,int &x,int &y){ 13 if(b==0){ 14 x=1; 15 y=0; 16 return a; 17 } 18 else{ 19 int ans=exgcd(b,a%b,x,y); 20 int t=x; 21 x=y; 22 y=t-a/b*y; 23 return ans; 24 } 25 } 26 27 int main(){ 28 cin>>a>>b; 29 int x,y; 30 x=y=0; 31 exgcd(a,b,x,y); 32 x=(x%b+b)%b; 33 cout<<x; 34 return 0; 35 }10.棧
?單擊此處看題目
?考察算法:記憶化搜索或者Catalan數推導公式
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 5 int n; 6 long long f=1; 7 8 int main(){ 9 cin>>n; 10 for(int i=2;i<=n;i++)f=f*(2*(2*i-1))/(i+1); 11 cout<<f; 12 return 0; 13 }11.八數碼難題
??單機此處看題目
?考察算法:
? ? 二B青年:暴力寬搜
? ? 普通青年:雙向廣搜
? ? 文藝青年:啟發式搜索(也就是我!(*^__^*) 嘻嘻……)
1 #include <iostream> 2 #include <cstdio> 3 #include <queue> 4 #include <cmath> 5 #include <cstring> 6 using namespace std; 7 8 const int MaxM=100000008; 9 const int OK[9][2]={{2,2},{1,1},{1,2},{1,3},{2,3},{3,3},{3,2},{3,1},{2,1}}; 10 11 bool apper[MaxM];//Hash 12 13 struct segment{ 14 int f,g,h;//估價函數 15 short a[10][10]; 16 int empty_x,empty_y; 17 segment(){f=g=h=0;} 18 friend bool operator< (segment a,segment b){ 19 return a.f>b.f; 20 } 21 }stat; 22 23 priority_queue<segment> q; 24 25 void init(){ 26 int i,j,x=0; 27 for(i=1;i<=3;i++) 28 for(j=1;j<=3;j++){ 29 scanf("%1d",&stat.a[i][j]); 30 x=x*10+stat.a[i][j]; 31 if(stat.a[i][j]==0)stat.empty_x=i,stat.empty_y=j; 32 } 33 q.push(stat); 34 memset(apper,false,sizeof(apper)); 35 apper[x/10]=true; 36 } 37 38 int get_corn(segment b){ 39 int x=0,i,j; 40 for(i=1;i<=3;i++) 41 for(j=1;j<=3;j++) 42 x=x*10+b.a[i][j]; 43 return x; 44 } 45 46 int Man_Ha_Dun(int x1,int y1,int x2,int y2){ 47 return abs(x1-x2)+abs(y1-y2); 48 } 49 50 int get_future(segment b){ 51 int i,j,total=0; 52 for(i=1;i<=3;i++) 53 for(j=1;j<=3;j++) 54 total+=Man_Ha_Dun(i,j,OK[b.a[i][j]][0],OK[b.a[i][j]][1]);//求出不在位將牌到初始位置的路徑總和作為啟發函數的一部分 55 return total; 56 } 57 58 void heuristic_search(){ 59 int i,j,t; 60 segment head; 61 while(!q.empty()){ 62 head=q.top(); 63 q.pop(); 64 if(get_corn(head)==123804765){cout<<head.g;return;} 65 if(head.empty_x-1>=1){ 66 swap(head.a[head.empty_x-1][head.empty_y],head.a[head.empty_x][head.empty_y]); 67 if(apper[get_corn(head)/10]==false){ 68 apper[get_corn(head)/10]=true; 69 head.g++; 70 t=head.h; 71 head.empty_x--; 72 head.h=get_future(head); 73 head.f=head.g+head.h;//更新啟發函數 74 q.push(head); 75 head.empty_x++; 76 head.g--;//還原狀態 77 head.h=t; 78 head.f=head.g+head.h; 79 } 80 swap(head.a[head.empty_x-1][head.empty_y],head.a[head.empty_x][head.empty_y]); 81 } 82 if(head.empty_y-1>=1){ 83 swap(head.a[head.empty_x][head.empty_y-1],head.a[head.empty_x][head.empty_y]); 84 if(apper[get_corn(head)/10]==false){ 85 apper[get_corn(head)/10]=true; 86 head.g++; 87 t=head.h; 88 head.empty_y--; 89 head.h=get_future(head); 90 head.f=head.g+head.h;//更新啟發函數 91 q.push(head); 92 head.empty_y++; 93 head.g--;//還原狀態 94 head.h=t; 95 head.f=head.g+head.h; 96 } 97 swap(head.a[head.empty_x][head.empty_y-1],head.a[head.empty_x][head.empty_y]); 98 } 99 if(head.empty_x+1<=3){ 100 swap(head.a[head.empty_x+1][head.empty_y],head.a[head.empty_x][head.empty_y]); 101 if(apper[get_corn(head)/10]==false){ 102 apper[get_corn(head)/10]=true; 103 head.g++; 104 t=head.h; 105 head.h=get_future(head); 106 head.empty_x++; 107 head.f=head.g+head.h;//更新啟發函數 108 q.push(head); 109 head.empty_x--; 110 head.g--;//還原狀態 111 head.h=t; 112 head.f=head.g+head.h; 113 } 114 swap(head.a[head.empty_x+1][head.empty_y],head.a[head.empty_x][head.empty_y]); 115 } 116 if(head.empty_y+1<=3){ 117 swap(head.a[head.empty_x][head.empty_y+1],head.a[head.empty_x][head.empty_y]); 118 if(apper[get_corn(head)/10]==false){ 119 apper[get_corn(head)/10]=true; 120 head.g++; 121 t=head.h; 122 head.h=get_future(head); 123 head.empty_y++; 124 head.f=head.g+head.h;//更新啟發函數 125 q.push(head); 126 head.empty_y--; 127 head.g--;//還原狀態 128 head.h=t; 129 head.f=head.g+head.h; 130 } 131 swap(head.a[head.empty_x][head.empty_y+1],head.a[head.empty_x][head.empty_y]); 132 } 133 } 134 } 135 136 int main(){ 137 init(); 138 heuristic_search(); 139 return 0; 140 }?============================動態規劃專題===============================
【線型DP】
1.乘積最大
2.最長公共子序列
3.最長不下降子序列
4.編輯距離
【背包DP】
1.烏龜棋
2.采藥
3.機器分配
【區間DP】
1.石子合并
2.能量項鏈
【棋盤DP】
1.免費餡餅
2.傳紙條
? ?單擊此處看題目
? 考察算法:雙向棋盤DP
? 設f(x1,y1,x2,y2)表示紙條1在(x1,y1),紙條2在(x2,y2)這個位置所能獲得的總的最大值
1 #include <iostream> 2 using namespace std; 3 4 int n,m,a[51][51]; 5 int f[51][51][51][51]; 6 7 int main(){ 8 cin>>n>>m; 9 int i,j,i1,j1,i2,j2; 10 for(i=1;i<=n;i++) 11 for(j=1;j<=m;j++) 12 cin>>a[i][j]; 13 for(i1=1;i1<=n;i1++) 14 for(j1=1;j1<=m;j1++) 15 for(i2=1;i2<=n;i2++) 16 for(j2=1;j2<=m;j2++) 17 if((i1!=i2 && j1!=j2) || (i1==i2 && j1==j2 && i1==n && j1==m)){ 18 f[i1][j1][i2][j2]=max(max(f[i1-1][j1][i2-1][j2],f[i1-1][j1][i2][j2-1]),max(f[i1][j1-1][i2-1][j2],f[i1][j1-1][i2][j2-1])); 19 f[i1][j1][i2][j2]+=a[i1][j1]+a[i2][j2]; 20 } 21 cout<<f[n][m][n][m]; 22 return 0; 23 }?
轉載于:https://www.cnblogs.com/maopengsen/p/4282412.html
總結
- 上一篇: 梦到怀孕要打掉是什么意思周公解梦
- 下一篇: 梦到自己养的花枯萎了是什么意思