hdu 6535 2018 CCPC吉林 K The Magician (大模拟)

一个简化版的回合制游戏(万智牌?)的游戏规则,要求你模拟出游戏结果。

官方题解:硬核模拟,写就行了。。。 (比赛时真没法写)

题目不难读,就是容易漏细节,写了2h+debug了2h+wa了1h才过。也没什么办法,以后读题要仔细,读完写的时候别把细节忘了,最好列出来。
这次用了一大堆STL压进两百行,而且写的还算清晰,按照几年前的码风估计得到400行。

  1. /*
  2. Author: fffasttime
  3. Date: 2019/07/21 15:00
  4. */
  5. #include <bits/stdc++.h>
  6. using namespace std;
  7. typedef long long ll;
  8. #define inc(i,n) for (int i=0;i<n;i++)
  9. #define DR(X) int X; scanf("%d",&X);
  10. const int N=100010;
  11.  
  12. int c[2][4][5];//deck,hand,field,grave //plain, swamp, mountain, island, forest
  13. vector<int> deck[2];
  14.  
  15. int opt[4][5]{
  16. {2,1,3,5,4},
  17. {3,4,2,1,5},
  18. {4,5,3,2,1},
  19. {5,2,3,4,1}};
  20. template <int tp>
  21. bool cmp(int x, int y){return opt[tp][x]<opt[tp][y];}
  22.  
  23. int turn,step;
  24.  
  25. void mv(int tr, int fr, int to, int d){
  26. 	//printf("player %d: %d , %d-->%d\n",tr, d, fr, to);
  27. 	assert(c[tr][fr][d]>0);
  28. 	c[tr][fr][d]--;
  29. 	c[tr][to][d]++;
  30. }
  31.  
  32. void draw(int tr=turn){
  33. 	if (deck[tr].empty()) return;
  34. 	//printf("(draw) ");
  35. 	int d=deck[tr].back(); 
  36. 	deck[tr].pop_back();
  37. 	mv(tr,0,1,d);
  38. }
  39.  
  40. void discard(int tr){
  41. 	int ocr=0;
  42. 	int sel[5],sc=0;
  43. 	inc(i,5) if (c[tr][1][i]){
  44. 		if (c[tr][1][i]>ocr){
  45. 			sc=0; ocr=c[tr][1][i];
  46. 			sel[sc++]=i;
  47. 		}
  48. 		else if (c[tr][1][i]==ocr){
  49. 			sel[sc++]=i;
  50. 		}
  51. 	}
  52. 	assert(sc);
  53. 	sort(sel,sel+sc,cmp<1>);
  54. 	//printf("(discard) ");
  55. 	mv(tr,1,3,sel[0]);
  56. }
  57.  
  58. void destroy(int tr){
  59. 	int ocr=100;
  60. 	int sel[5],sc=0;
  61. 	inc(i,5) if (c[tr][2][i]){
  62. 		if (c[tr][2][i]<ocr){
  63. 			sc=0; ocr=c[tr][2][i];
  64. 			sel[sc++]=i;
  65. 		}
  66. 		else if (c[tr][2][i]==ocr){
  67. 			sel[sc++]=i;
  68. 		}
  69. 	}
  70. 	assert(sc);
  71. 	sort(sel,sel+sc,cmp<2>);
  72. 	//printf("(destroy) ");
  73. 	mv(tr,2,3,sel[0]);
  74. }
  75. void recycle(int tr){
  76. 	int ocr=100;
  77. 	int sel[5],sc=0;
  78. 	inc(i,5) if (c[tr][3][i]){
  79. 		if (c[tr][2][i]+c[tr][1][i]<ocr){
  80. 			sc=0; ocr=c[tr][2][i]+c[tr][1][i];
  81. 			sel[sc++]=i;
  82. 		}
  83. 		else if (c[tr][2][i]+c[tr][1][i]==ocr){
  84. 			sel[sc++]=i;
  85. 		}
  86. 	}
  87. 	assert(sc);
  88. 	sort(sel,sel+sc,cmp<3>);
  89. 	//printf("(recycle) ");
  90. 	mv(tr,3,1,sel[0]);
  91. }
  92.  
  93. void eff(int d){ //type
  94. 	switch(d){
  95. 		case 0: draw(); break;
  96. 		case 1: discard(!turn); break;
  97. 		case 2: destroy(!turn); break;
  98. 		case 4: recycle(turn); break;
  99. 	}
  100. }
  101.  
  102. bool cheff(int d){
  103. 	switch(d){
  104. 		case 0: return deck[turn].size();
  105. 		case 1: {
  106. 			inc(i,5) if (c[!turn][1][i]) return 1;
  107. 			return 0;
  108. 		}
  109. 		case 2:{
  110. 			inc(i,5) if (c[!turn][2][i]) return 1;
  111. 			return 0;
  112. 		}
  113. 		case 4:{
  114. 			inc(i,5) if (c[turn][3][i]) return 1;
  115. 			return 0;
  116. 		}
  117. 	}
  118. 	return 0; //island
  119. }
  120.  
  121. bool counter(int d){
  122. 	if (c[!turn][1][3]<1 || accumulate(c[!turn][1],c[!turn][1]+5,0)<2) return 0;
  123. 	if (count_if(c[turn][2],c[turn][2]+5,[](int x){return x;})<4) return 0;
  124. 	for (int i=0;i<5;i++) if (c[turn][2][i]==0 && c[turn][3][i]>=5) return 0;
  125. 	mv(turn,1,3,d);
  126. 	mv(!turn,1,3,3); //counter
  127. 	discard(!turn);
  128. 	return 1;
  129. }
  130.  
  131. void play(){
  132. 	int p[5]; //play type
  133. 	int pri=0,pc=0;
  134. 	inc(i,5) if (c[turn][1][i]){
  135. 		int np;
  136. 		if (c[turn][2][i]) np=1;
  137. 		else{
  138. 			if (cheff(i)) np=3;
  139. 			else np=2;
  140. 		}
  141. 		if (np>pri){
  142. 			pc=0; pri=np;
  143. 			p[pc++]=i;
  144. 		}
  145. 		else if (np==pri){
  146. 			p[pc++]=i;
  147. 		}
  148. 	}
  149. 	if (pri<2) return;
  150. 	if (pc>1)
  151. 		sort(p,p+pc,cmp<0>);
  152. 	int cur=p[0];
  153. 	if (counter(cur)){
  154. 		return;
  155. 	}
  156. 	//printf("(play) ");
  157. 	mv(turn,1,2,cur);
  158. 	if (pri==3) eff(cur);
  159. }
  160.  
  161. void solve(){
  162. 	memset(c,0,sizeof c);
  163. 	deck[0].clear(); deck[1].clear();
  164. 	inc(i,25) {DR(t) c[0][0][t]++; deck[0].push_back(t);}
  165. 	inc(i,25) {DR(t) c[1][0][t]++; deck[1].push_back(t);}
  166. 	turn=0,step=1;
  167. 	reverse(deck[0].begin(), deck[0].end());
  168. 	reverse(deck[1].begin(), deck[1].end());
  169. 	inc(i,5) draw(0);
  170.    	inc(i,5) draw(1);	
  171. 	while (1){
  172. 		draw();
  173. 		play();
  174. 		if (step>=100 || all_of(c[turn][2],c[turn][2]+5, [](int x){return x;}))
  175. 			break;
  176. 		if (none_of(c[turn][0],c[turn][0]+10,[](int x){return x;}) 
  177. 		&&none_of(c[!turn][0],c[!turn][0]+10,[](int x){return x;}))
  178. 			break;
  179. 		turn=!turn;
  180. 		//for (int j=0;j<4;j++,cout<<'\n') inc(i,5) printf("%d ",c[0][j][i]); //printf(";");
  181. 		//for (int j=0;j<4;j++,cout<<'\n') inc(i,5) printf("%d ",c[1][j][i]); printf("%d",step);
  182. 		step++;
  183. 		//puts("---------");
  184. 	}
  185. 	if (all_of(c[turn][2],c[turn][2]+5, [](int x){return x;})){
  186. 		printf("%s",step&1?"Alice":"Bob");
  187. 	}
  188. 	else printf("Draw");
  189. 	printf(" %d\n", step);
  190. }
  191.  
  192. int main(){
  193. 	int T; cin>>T;
  194. 	for (int i=1;i<=T;i++){
  195. 		printf("Case %d: ",i);
  196. 		solve();
  197. 	}
  198. 	return 0;
  199. }

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注