Luogu2482 [SDOI2010]猪国杀

题意

......

https://www.luogu.org/problemnew/show/P2482

总结

题解好像没什么好写的

一些经验吧......

  1. 提前分配好一些比较好的变量名
  2. 建议先声明函数再定义函数
  3. 打开Dev-C++的代码结构或者自己在草稿纸上写结构
  4. 每次调试之前自己浏览一遍代码并手推一遍样例,特别是修改了之后注意自己修改的地方,不要编译了历史版本
  5. 不要写的十分复杂,能简单写简单写
  6. 善用assert
  7. 善用注释

   1 //Created By Creeper_LKF
   2 //Caution::We used "pragma" in the code
   3 #include <cstdio>
   4 #include <cctype>
   5 #include <cassert>
   6 #include <cstdlib>
   7 #include <cstring>
   8 #include <iostream>
   9
  10 #ifdef __gnu_linux__
  11
  12 #include <fcntl.h>
  13 #include <unistd.h>
  14 #include <sys/mman.h>
  15
  16 #endif
  17
  18 #if __cplusplus < 201103L
  19
  20 #include <stdarg.h>
  21
  22 #endif
  23
  24 //Algorithm Heads
  25
  26 #include <list>
  27 #include <queue>
  28 #include <vector>
  29
  30 using namespace std;
  31
  32 //FILE_NAME DEFINATION
  33
  34 const char file_name[] = "b";
  35
  36 #define NAME_SPACE
  37 #define USING
  38
  39 #ifdef NAME_SPACE
  40 namespace LKF{
  41 #endif
  42     #define SF_READ
  43     #define EOF_READ
  44     // #define NEED_FILE
  45     // #define WRITE_ENDL
  46     // #define FAST_WRITE
  47     const size_t MAX_BUF_SIZE = 50000000;
  48
  49     #ifdef FAST_WRITE
  50     char outp[MAX_BUF_SIZE], *op = outp;
  51     #endif
  52
  53     #ifdef DONLINE_JUDGE
  54     #undef NEED_FILE
  55     #endif
  56
  57     #ifdef FAST_WRITE
  58     #ifndef WRITE_ENDL
  59     #define WRITE_ENDL
  60     #endif
  61     #endif
  62
  63     extern inline void FILE_OPT(){
  64         #ifdef NEED_FILE
  65         #define FILE_NAME file_name
  66         char IN_FILE[sizeof(FILE_NAME) + 5], OUT_FILE[sizeof(FILE_NAME) + 5];
  67         strcpy(IN_FILE, FILE_NAME), strcpy(OUT_FILE, FILE_NAME);
  68         strcat(IN_FILE, ".in"), strcat(OUT_FILE, ".out");
  69         freopen(IN_FILE, "r", stdin);
  70         freopen(OUT_FILE, "w", stdout);
  71         #endif
  72     }
  73
  74     #ifdef __gnu_linux__
  75
  76     char *pc;
  77
  78     extern inline void Main_Init(){
  79         static bool INITED = false;
  80         if(INITED){
  81             #ifdef FAST_WRITE
  82             fwrite(outp, 1, op - outp - 1, stdout);
  83             #endif
  84             fclose(stdin), fclose(stdout);
  85         } else {
  86             FILE_OPT();
  87             pc = (char *) mmap(NULL, lseek(0, 0, SEEK_END), PROT_READ, MAP_PRIVATE, 0, 0);
  88             INITED = true;
  89         }
  90     }
  91
  92     #else
  93
  94     char buf[MAX_BUF_SIZE], *pc = buf;
  95
  96     extern inline void Main_Init(){
  97         static bool INITED = false;
  98         if(INITED){
  99             #ifdef FAST_WRITE
 100             fwrite(outp, 1, op - outp - 1, stdout);
 101             #endif
 102             fclose(stdin), fclose(stdout);
 103         } else {
 104             FILE_OPT();
 105             fread(buf, 1, MAX_BUF_SIZE, stdin);
 106             INITED = true;
 107         }
 108     }
 109
 110     #endif
 111
 112     #ifdef EOF_READ
 113
 114     #ifdef SF_READ
 115
 116     template<typename T>
 117     static inline void read(T &num){
 118         num = 0;
 119         char c, sf = 1;
 120         while(isspace(c = *pc++));
 121         if(c == 45) sf = -1, c = *pc ++;
 122         while(num = num * 10 + c - 48, isdigit(c = *pc++));
 123         num *= sf;
 124     }
 125
 126     static inline int read(){
 127         int num = 0;
 128         char c, sf = 1;
 129         while(isspace(c = *pc++));
 130         if(c == 45) sf = -1, c = *pc ++;
 131         while(num = num * 10 + c - 48, isdigit(c = *pc++));
 132         return num * sf;
 133     }
 134
 135     #else
 136
 137     template<typename T>
 138     static inline T read(T &num){
 139         num = 0;
 140         char c;
 141         while (isspace(c = *pc++));
 142         while (num = num * 10 + c - 48, isdigit(c = *pc++));
 143         return num;
 144     }
 145
 146     static inline int read(){
 147         int num = 0;
 148         char c;
 149         while (isspace(c = *pc++));
 150         while (num = num * 10 + c - 48, isdigit(c = *pc++));
 151         return num;
 152     }
 153
 154     #endif
 155
 156     #else
 157
 158     #ifdef SF_READ
 159
 160     template<typename T>
 161     static inline void read(T &num){
 162         num = 0;
 163         char c, sf = 1;
 164         while((c = *pc++) < 45);
 165         if(c == 45) sf = -1, c = *pc ++;
 166         while(num = num * 10 + c - 48, (c = *pc++) >= 48);
 167         num *= sf;
 168     }
 169
 170     static inline int read(){
 171         int num = 0;
 172         char c, sf = 1;
 173         while((c = *pc++) < 45);
 174         if(c == 45) sf = -1, c = *pc ++;
 175         while(num = num * 10 + c - 48, (c = *pc++) >= 48);
 176         return num * sf;
 177     }
 178
 179     #else
 180
 181     template<typename T>
 182     static inline T read(T &num){
 183         num = 0;
 184         char c;
 185         while ((c = *pc++) < 48);
 186         while (num = num * 10 + c - 48, (c = *pc++) >= 48);
 187         return num;
 188     }
 189
 190     static inline int read(){
 191         int num = 0;
 192         char c;
 193         while ((c = *pc++) < 48);
 194         while (num = num * 10 + c - 48, (c = *pc++) >= 48);
 195         return num;
 196     }
 197
 198     #endif
 199
 200     #endif
 201
 202     #ifdef FAST_WRITE
 203     template <typename T>
 204     inline void Call_Write(char Split, T tar){
 205         char buf[20];
 206         int top = 0;
 207         if(tar == 0) *op ++ = 48;
 208         else {
 209             if(tar < 0) *op ++ = ‘-‘;
 210             while(tar) buf[++top] = tar % 10, tar /= 10;
 211             while(top) *op ++ = buf[top --] ^ 48;
 212         }
 213         *op ++ = Split;
 214     }
 215     template <typename T>
 216     inline void Call_Write(T tar){
 217         char buf[20];
 218         int top = 0;
 219         if(tar == 0) *op ++ = 48;
 220         else {
 221             if(tar < 0) *op ++ = ‘-‘;
 222             while(tar) buf[++top] = tar % 10, tar /= 10;
 223             while(top) *op ++ = buf[top --] ^ 48;
 224         }
 225     }
 226     #endif
 227
 228     #ifdef FAST_WRITE
 229
 230     extern inline void write(){
 231         *op ++ = ‘\n‘;
 232     }
 233
 234     template<typename T>
 235     extern inline void write(T tar){
 236         Call_Write(tar);
 237         #ifdef WRITE_ENDL
 238         write();
 239         #endif
 240     }
 241
 242     #if __cplusplus >= 201103L
 243
 244     # pragma GCC diagnostic push
 245     # pragma GCC diagnostic ignored "-Wunused-parameter"
 246
 247     template<typename T>
 248     extern inline void write(char Split, T tar){
 249         Call_Write(tar);
 250         #ifdef WRITE_ENDL
 251         write();
 252         #endif
 253     }
 254
 255     # pragma GCC diagnostic pop
 256     # pragma message "Warning : pragma used"
 257
 258     template<typename Head, typename T, typename... Tail>
 259     extern inline void write(char Split, Head head, T mid, Tail... tail){
 260         Call_Write(Split, head);
 261         write(Split, mid, tail...);
 262     }
 263
 264     #else
 265
 266     template <typename T>
 267     extern inline void write(char Split, T tar){
 268         Call_Write(tar);
 269         #ifdef WRITE_ENDL
 270         write();
 271         #endif
 272     }
 273
 274     #endif
 275
 276     #else
 277
 278     extern inline void write(){
 279         cout << endl;
 280     }
 281
 282     template<typename T>
 283     extern inline void write(T tar){
 284         cout << tar;
 285         #ifdef WRITE_ENDL
 286         write();
 287         #endif
 288     }
 289
 290     #if __cplusplus >= 201103L
 291
 292     template<typename T>
 293     extern inline void write(char Split, T tar){
 294         cout << tar << Split;
 295     }
 296
 297     template<typename Head, typename T, typename... Tail>
 298     extern inline void write(char Split, Head head, T mid, Tail... tail){
 299         cout << head;
 300         write(Split, mid, tail...);
 301     }
 302
 303     #else
 304
 305     template <typename T>
 306     extern inline void write(char Split, T tar){
 307         cout << tar << Split;
 308         #ifdef WRITE_ENDL
 309         write();
 310         #endif
 311     }
 312
 313     #endif
 314
 315     #endif
 316
 317     template <typename T>
 318     extern inline void upmax(T &x, const T &y){
 319         if(x < y) x = y;
 320     }
 321     template <typename T>
 322     extern inline void upmin(T &x, const T &y){
 323         if(x > y) x = y;
 324     }
 325
 326     #if __cplusplus >= 201103L
 327
 328     template<typename T>
 329     extern inline T max(T tar){
 330         return tar;
 331     }
 332
 333     template<typename T>
 334     extern inline T min(T tar){
 335         return tar;
 336     }
 337
 338     template <typename Head, typename T, typename... Tail>
 339     extern inline Head max(Head head, T mid, Tail... tail){
 340         Head tmp = max(mid, tail...);
 341         return head > tmp ? head : tmp;
 342     }
 343     template <typename Head, typename T, typename... Tail>
 344     extern inline Head min(Head head, T mid, Tail... tail){
 345         Head tmp = min(mid, tail...);
 346         return head < tmp ? head : tmp;
 347     }
 348
 349     #else
 350
 351     template <typename T>
 352     extern inline T max(T a, T b){
 353         return a > b ? a : b;
 354     }
 355     template <typename T>
 356     extern inline T min(T a, T b){
 357         return a < b ? a : b;
 358     }
 359
 360     #endif
 361
 362     template <typename T>
 363     extern inline T abs(T tar){
 364         return tar < 0 ? -tar : tar;
 365     }
 366     template <typename T>
 367     extern inline void swap(T &a, T &b){
 368         int t = a;
 369         a = b;
 370         b = t;
 371     }
 372 #ifdef NAME_SPACE
 373 }
 374 #endif
 375
 376 //Algorithm
 377
 378 #ifdef NAME_SPACE
 379 namespace LKF{
 380 #endif
 381
 382     template <typename T>
 383     struct Queue{
 384         size_t s, t;
 385         T *q;
 386         Queue(){
 387             s = 1, t = 0;
 388             q = NULL;
 389         }
 390         Queue(size_t siz){
 391             q = (T*)malloc(sizeof(T) * siz);
 392             assert(q != NULL);
 393         }
 394         ~Queue(){
 395             delete[] q;
 396         }
 397         inline void clear(){
 398             s = 1, t = 0;
 399         }
 400         inline bool empty(){
 401             return s > t;
 402         }
 403         inline size_t size(){
 404             return t - s + 1;
 405         }
 406         inline void push(T tar){
 407             q[++t] = tar;
 408         }
 409         inline void pop_front(){
 410             s++;
 411         }
 412         inline void pop_back(){
 413             t++;
 414         }
 415         inline T front(){
 416             return q[s];
 417         }
 418         inline T back(){
 419             return q[t];
 420         }
 421     };
 422
 423 #ifdef NAME_SPACE
 424 }
 425 #endif
 426
 427 #ifdef USING
 428
 429 #ifdef NAME_SPACE
 430 using LKF::read;
 431 using LKF::Main_Init;
 432 using LKF::write;
 433 using LKF::upmax;
 434 using LKF::upmin;
 435 using LKF::max;
 436 using LKF::min;
 437 using LKF::abs;
 438 // using LKF::swap;
 439 #else
 440 using ::read;
 441 using ::Main_Init;
 442 using ::write;
 443 using ::upmax;
 444 using ::upmin;
 445 using ::max;
 446 using ::min;
 447 using ::abs;
 448 // using ::swap;
 449 #endif
 450
 451 #endif
 452
 453 //Source Code
 454
 455 using namespace std;
 456
 457 typedef list<int> CARD;
 458
 459 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Debug_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 460 #if DEBUG
 461
 462 //Caution: Do Not Inline
 463 //Do Not Open In Dev_CPP
 464
 465 void Print_Array(int s, int t, int *arr, string Name){
 466     cout << Name << " Begin" << endl;
 467     for(int i = s; i < t; i++) cout << arr[i] << ‘ ‘;
 468     cout << Name << " End" << endl;
 469 }
 470
 471 void Print_List(CARD::iterator B, CARD::iterator E, string Name){
 472     cout << Name << " Begin" << endl;
 473     for(CARD::iterator it = B; it != E; it++)
 474         cout << *it << ‘ ‘;
 475     cout << Name << " End" << endl;
 476 }
 477
 478
 479 #endif
 480 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Read_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 481 //This is SDOI2010 Killer of Pig Kingdom
 482 //This is Release Version
 483
 484 inline char get_c(){
 485     char c;
 486     while(!isalpha(c = *LKF::pc ++));
 487     return c;
 488 }
 489
 490 //Caution::
 491 //Do not omit parentheses
 492
 493 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Const_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 494
 495 const int MAXN = 15, MAXM = 2018;//数组大小
 496 const int GA = 0, MA = 1;//献殷勤,表敌意
 497 const int ING = 0, MPG = 1, FPG = 2;//游戏状态
 498 const int MP = 1, ZP = 2, AP = 3;//人物身份类型IDF,主猪,忠猪,反猪(同时表示主猪位置)
 499 const int NN = 0, NS = 1, BZ = 2, BF = 3;//表示状态,未跳,类反猪,跳忠,跳反
 500 const int P = 1, K = 2, D = 3;//基础类:桃,杀,闪
 501 const int F = 4, N = 5, W = 6, J = 7;//技能类:决斗,南蛮入侵,万箭齐发,无懈可击
 502 const int Z = 8;//装备类:诸葛连弩
 503 const int FAIL = 0, SUCCEED = 1, GAME_OVER = 2;
 504
 505 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Variable_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 506
 507 int n, m, ReM, HP, FZ, Man_Now;
 508 int Heap[MAXM];
 509 int Game_State;
 510
 511 struct Pig{
 512     int IDF, Health, IDS;//身份,血量,表态
 513     int HC_CNT[MAXN], Dis[MAXN];//每种牌统计,距离
 514     bool Death, ST_Z, ST_K;//死亡标记,诸葛连弩装备状态,出杀状态
 515     CARD HC;//要求每次访问之前都有相应元素
 516     Pig(){
 517         Death = false;
 518         Health = 4;
 519         IDF = 0;
 520         HC.clear();
 521     }
 522     inline void Add(int tar){//摸牌
 523         HC.push_back(tar);
 524         HC_CNT[tar]++;
 525     }
 526     inline int Get(){//出牌
 527         int tar = HC.front();
 528         HC.pop_front();
 529         HC_CNT[tar]--;
 530         return tar;
 531     }
 532     inline int Card(int Knd, int Num){//要求严格存在这些牌
 533         CARD::iterator it;
 534         int tim = 0;
 535         for(it = HC.begin(); it != HC.end(); it++){
 536             if(*it == Knd){
 537                 HC.erase(it);
 538                 HC_CNT[Knd]--;
 539                 tim++;
 540             }
 541             if(tim == Num) break;
 542         }
 543         #if DEBUG
 544         assert(tim == Num);
 545         #endif
 546         return tim;
 547     }
 548 }pig[MAXN];
 549
 550 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Mini_Function__Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 551
 552 inline int CTI(char tar){
 553     switch(tar){
 554         case ‘P‘ : return P;
 555         case ‘K‘ : return K;
 556         case ‘D‘ : return D;
 557         case ‘F‘ : return F;
 558         case ‘N‘ : return N;
 559         case ‘W‘ : return W;
 560         case ‘J‘ : return J;
 561         case ‘Z‘ : return Z;
 562     }
 563     return 0;
 564 }
 565
 566 inline char ITC(int tar){
 567     static char ret[10] = {0, ‘P‘, ‘K‘, ‘D‘, ‘F‘, ‘N‘, ‘W‘, ‘J‘, ‘Z‘, 0};
 568     return ret[tar];
 569 }
 570
 571 inline int Deal_Card(){//不早说
 572     if(HP == m) return Heap[m];
 573     return Heap[++HP];
 574 }
 575
 576 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Declaring_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 577
 578 inline void Input();
 579
 580 inline void Solve();
 581
 582 inline void Output();
 583
 584 inline int New_Round(int);
 585
 586 inline void Reset_Dis();
 587
 588 inline int Kill(int, int);
 589
 590 inline int DeaD(int, int);
 591
 592 inline int Dec_Health(int, int);
 593
 594 inline void Gallant(int, int);
 595
 596 inline void Malicious(int, int);
 597
 598 //被调用出牌 开始
 599
 600 inline int Pas_P(int);
 601 inline int Pas_K(int, int);
 602 inline int Pas_D(int);
 603 inline int Pas_F(int, int);
 604 inline int Pas_N(int);
 605 inline int Pas_W(int);
 606 inline int Pas_J(int, int, int);
 607 inline int Pas_Z(int);
 608
 609 //被调用出牌 结束
 610
 611 //主动出牌 开始
 612
 613 inline int Cal_P(int);
 614 inline int Cal_K(int);
 615 inline int Cal_D(int, int);
 616 inline int Cal_F(int);
 617 inline int Cal_N(int);
 618 inline int Cal_W(int);
 619 inline int Cal_J(int, int, int);
 620 inline int Cal_Z(int);
 621
 622 //主动出牌 结束
 623
 624 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Main_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 625
 626 int main(){
 627     Main_Init();
 628     Input();
 629     Solve();
 630     Output();
 631     return 0;
 632 }
 633
 634 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Function_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 635
 636 inline void Input(){
 637     ReM = n = read(), m = read();
 638     for(int i = 1; i <= n; i++){
 639         char idf = get_c();
 640         switch(idf){
 641             case ‘M‘ : pig[i].IDF = MP; break;
 642             case ‘Z‘ : pig[i].IDF = ZP; break;
 643             case ‘F‘ : pig[i].IDF = AP, FZ++; break;
 644         }
 645         get_c();
 646         for(int j = 1; j <= 4; j++) pig[i].Add(CTI(get_c()));
 647     }
 648     for(int i = 1; i <= m; i++) Heap[i] = CTI(get_c());
 649 }
 650
 651 inline void Solve(){
 652     if(FZ == 0){
 653         Game_State = MPG;
 654         return ;
 655     }
 656     Reset_Dis();
 657     while(Game_State == ING){
 658         Man_Now++;
 659         if(Man_Now == n + 1) Man_Now = 1;
 660         if(pig[Man_Now].Death) continue;
 661         New_Round(Man_Now);
 662     }
 663 }
 664
 665 inline void Output(){
 666     write(‘\n‘, Game_State == MPG ? "MP" : "FP");
 667     for(int i = 1; i <= n; i++){
 668         if(pig[i].Death) write(‘\n‘, "DEAD");
 669         else {
 670             CARD::iterator it;
 671             for(it = pig[i].HC.begin(); it != pig[i].HC.end(); it++){
 672                 write(‘ ‘, ITC(*it));
 673             }
 674             write();
 675         }
 676     }
 677 }
 678
 679 inline int New_Round(int Man){//注意:每次都会重新刷新序列(从头开始)
 680     pig[Man].Add(Deal_Card()), pig[Man].Add(Deal_Card());
 681     pig[Man].ST_K = false;
 682     CARD::iterator it;
 683     int ret = 0, tar = 0;
 684 //    Print_List(pig[3].HC.begin(), pig[3].HC.end(), "3");
 685     for(it = pig[Man].HC.begin(); !pig[Man].Death && Game_State == ING && it != pig[Man].HC.end(); ){
 686         tar = *it, ret = 0;
 687         switch(tar){
 688             case P : ret = Cal_P(Man); break;
 689             case K : if(!pig[Man].ST_K || pig[Man].ST_Z) ret = bool(Cal_K(Man)), pig[Man].ST_K = ret; break;
 690             // case D : ret = Cal_D(Man); break;
 691             case F : ret = Cal_F(Man); break;
 692             case N : ret = Cal_N(Man), ret = 1; break;
 693             case W : ret = Cal_W(Man), ret = 1; break;
 694             // case J : ret = Cal_J(Man); break;
 695             case Z : ret = Cal_Z(Man), ret = 1; break;
 696         }//要求在各函数内完成牌数统计
 697         if(ret == FAIL) it++;
 698         else it = pig[Man].HC.begin();
 699     }
 700     return SUCCEED;
 701 }
 702
 703 inline void Reset_Dis(){
 704     for(int i = 1; i <= n; i++){
 705         if(pig[i].Death) continue;
 706         pig[i].Dis[i] = 0;
 707         for(int j = i - 1, dis_now = ReM; j >= 1; j--){
 708             if(pig[j].Death) pig[i].Dis[j] = 0;
 709             else pig[i].Dis[j] = --dis_now;
 710         }
 711         for(int j = i + 1, dis_now = 0; j <= n; j++){
 712             if(pig[j].Death) pig[i].Dis[j] = 0;
 713             else pig[i].Dis[j] = ++dis_now;
 714         }
 715     }
 716 }
 717
 718 inline int Dead(int dst, int scr){//返回0表示未死亡,返回1表示死亡,返回2表示游戏结束
 719     if(pig[dst].HC_CNT[P] == 0) return bool(Kill(dst, scr)) + 1;
 720     Pas_P(dst);
 721     return FAIL;
 722 }
 723
 724 inline int Kill(int dst, int scr){//返回0表示游戏继续,返回1表示MP胜利(状态MPG),返回2表示AP胜利(状态FPG)
 725     pig[dst].Death = true;
 726     pig[dst].ST_Z = false;
 727     pig[dst].HC.clear();
 728     for(int i = 1; i < 10; i++) pig[dst].HC_CNT[i] = 0;
 729     ReM--;
 730     if(pig[dst].IDF == MP) return Game_State = FPG;
 731     if(pig[dst].IDF == AP){
 732         FZ --;
 733         if(!FZ) return Game_State = MPG;
 734         pig[scr].Add(Deal_Card()), pig[scr].Add(Deal_Card()), pig[scr].Add(Deal_Card());
 735     }
 736     if(pig[dst].IDF == ZP && pig[scr].IDF == MP){
 737         pig[scr].ST_Z = false;
 738         pig[scr].HC.clear();
 739         for(int i = 1; i < 10; i++) pig[scr].HC_CNT[i] = 0;
 740     }
 741     Reset_Dis();
 742     return Game_State = ING;
 743 }
 744
 745 inline int Dec_Health(int dst, int scr){//返回0表示未死亡,返回1表示已死亡,返回2表示游戏结束
 746     pig[dst].Health --;
 747     if(pig[dst].Health == 0) return Dead(dst, scr);
 748     return FAIL;
 749 }
 750
 751 inline void Malicious(int dst, int scr){
 752     if(pig[scr].IDF == MP) return ;
 753     #if DEBUG
 754     if(pig[dst].IDF == MP || pig[dst].IDS == BZ){
 755         assert(pig[scr].IDF != ZP);
 756         pig[scr].IDS = BF;
 757     } else if(pig[dst].IDS == BF){
 758         assert(pig[scr].IDF != AP);
 759         pig[scr].IDS = BZ;
 760     }
 761     #endif
 762     #if !DEBUG
 763     if(pig[dst].IDF == MP || pig[dst].IDS == BZ) pig[scr].IDS = BF;
 764     else if(pig[dst].IDS == BF) pig[scr].IDS = BZ;
 765     #endif
 766 }
 767
 768 inline void Gallant(int dst, int scr){
 769     if(pig[scr].IDF == MP) return ;
 770     #if DEBUG
 771     if(pig[dst].IDF == MP || pig[dst].IDS == BZ){
 772         assert(pig[scr].IDF != AP);
 773         pig[scr].IDS = BZ;
 774     } else if(pig[dst].IDS == BF){
 775         assert(pig[scr].IDF != ZP);
 776         pig[scr].IDS = BF;
 777     }
 778     #endif
 779     #if !DEBUG
 780     if(pig[dst].IDF == MP || pig[dst].IDS == BZ) pig[scr].IDS = BZ;
 781     else if(pig[dst].IDS == BF) pig[scr].IDS = BF;
 782     #endif
 783 }
 784
 785 inline int Cal_P(int Man){
 786     if(Pas_P(Man)) return SUCCEED;
 787     return FAIL;
 788 }
 789
 790 inline int Pas_P(int Man){//要求每次只加1血
 791     if(pig[Man].Health == 4 || pig[Man].HC_CNT[P] == 0) return FAIL;
 792     pig[Man].Card(P, 1);
 793     pig[Man].Health ++;
 794     return SUCCEED;
 795 }
 796
 797 inline int Cal_K(int Man){//主动杀部分
 798     if(pig[Man].IDF == MP){
 799         for(int i = 1; i < n; i++){
 800             int j = Man + i;
 801             if(j > n) j = j - n;
 802             if(pig[j].Death || pig[Man].Dis[j] > 1) continue;
 803             if(pig[j].IDS == BF || pig[j].IDS == NS){
 804                 Pas_K(j, Man);
 805                 return Cal_D(j, Man) == GAME_OVER ? GAME_OVER : SUCCEED;
 806             }
 807         }
 808         return FAIL;
 809     }
 810     if(pig[Man].IDF == ZP){
 811         for(int i = 1; i < n; i++){
 812             int j = Man + i;
 813             if(j > n) j = j - n;
 814             if(pig[j].Death || pig[Man].Dis[j] > 1) continue;
 815             if(pig[j].IDS == BF){
 816                 Pas_K(j, Man);
 817                 return Cal_D(j, Man) == GAME_OVER ? GAME_OVER : SUCCEED;
 818             }
 819         }
 820         return FAIL;
 821     }
 822     if(pig[Man].IDF == AP){
 823         if(pig[Man].Dis[MP] <= 1){
 824             Pas_K(MP, Man);
 825             return Cal_D(MP, Man) == GAME_OVER ? GAME_OVER : SUCCEED;
 826         }
 827         for(int i = 1; i < n; i++){
 828             int j = Man + i;
 829             if(j > n) j = j - n;
 830             if(pig[j].Death || pig[Man].Dis[j] > 1) continue;
 831             if(pig[j].IDF == MP || pig[j].IDS == BZ){
 832                 Pas_K(j, Man);
 833                 return Cal_D(j, Man) == GAME_OVER ? GAME_OVER : SUCCEED;
 834             }
 835         }
 836         return FAIL;
 837     }
 838     return FAIL;
 839 }
 840
 841 inline int Pas_K(int dst, int scr){//允许对id=0的猪判断身份
 842     if(dst) Malicious(dst, scr);
 843     if(pig[scr].HC_CNT[K] == 0) return FAIL;
 844     pig[scr].Card(K, 1);
 845     return SUCCEED;
 846 }
 847
 848 inline int Cal_D(int dst, int scr){
 849     if(Pas_D(dst) == FAIL) return Dec_Health(dst, scr);
 850     return FAIL;
 851 }
 852
 853 inline int Pas_D(int dst){//注意要求dst的方向与K不同
 854     if(pig[dst].HC_CNT[D] == 0) return FAIL;
 855     pig[dst].Card(D, 1);
 856     return SUCCEED;
 857 }
 858
 859 inline int Cal_F(int Man){//返回是否成功出牌
 860     if(pig[Man].IDF == MP){
 861         for(int i = 1; i < n; i++){
 862             int j = Man + i;
 863             if(j > n) j = j - n;
 864             if(pig[j].Death) continue;
 865             if(pig[j].IDS == BF || pig[j].IDS == NS){
 866                 return Pas_F(j, Man), SUCCEED;
 867             }
 868         }
 869         return FAIL;
 870     }
 871     if(pig[Man].IDF == ZP){
 872         for(int i = 1; i < n; i++){
 873             int j = Man + i;
 874             if(j > n) j = j - n;
 875             if(pig[j].Death) continue;
 876             if(pig[j].IDS == BF){
 877                 return Pas_F(j, Man), SUCCEED;
 878             }
 879         }
 880         return FAIL;
 881     }
 882     if(pig[Man].IDF == AP){//直接表主猪
 883         return Pas_F(MP, Man), SUCCEED;
 884         /*for(int i = 1; i < n; i++){
 885             int j = Man + i;
 886             if(j > n) j = j - n;
 887             if(pig[j].Death) continue;
 888             if(pig[j].IDF == MP || pig[j].IDS == BZ){
 889                 return Pas_F(j, Man);
 890             }
 891         }
 892         return FAIL;*/
 893     }
 894     return FAIL;
 895 }
 896
 897 inline int Pas_F(int dst, int scr){//返回scr出杀的数量
 898     Malicious(dst, scr);
 899     pig[scr].Card(F, 1);
 900     if(Cal_J(dst, scr, GA)) return FAIL;
 901     #if DEBUG
 902     assert(!(pig[dst].IDF == MP && pig[scr].IDF == ZP));
 903     #endif
 904     if(pig[dst].IDF == ZP && pig[scr].IDF == MP) return Dec_Health(dst, scr), 0;//主猪与忠猪的故事
 905     int ret = 0;
 906     while(true){
 907         if(Pas_K(0, dst) == FAIL) return Dec_Health(dst, scr), ret;
 908         if(Pas_K(0, scr) == FAIL) return Dec_Health(scr, dst), ret;//WTF???
 909         ret++;
 910     }
 911 }
 912
 913 inline int Cal_J(int dst, int scr, int State){//使用无懈可击的发起方(枚举)是对接收方献殷勤还是表敌意,scr用于枚举起点
 914     if(State == GA){//献殷勤,要求同边。注意逻辑不同,这里是枚举发起方,发起方知道自己的身份
 915         if(pig[dst].IDF == MP){
 916             for(int i = 0; i < n; i++){
 917                 int j = scr + i;
 918                 if(j > n) j = j - n;
 919                 if(pig[j].Death) continue;
 920                 if(pig[j].IDF == MP || pig[j].IDF == ZP){
 921                     if(Pas_J(dst, j, GA)) return Cal_J(j, j, MA) ? FAIL : SUCCEED;
 922                 }
 923             }
 924             return FAIL;
 925         } else if(pig[dst].IDS == BZ){
 926             for(int i = 0; i < n; i++){
 927                 int j = scr + i;
 928                 if(j > n) j = j - n;
 929                 if(pig[j].Death) continue;
 930                 if(pig[j].IDF == ZP || pig[j].IDF == MP){
 931                     if(Pas_J(dst, j, GA)) return Cal_J(j, j, MA) ? FAIL : SUCCEED;
 932                 }
 933             }
 934             return FAIL;
 935         } else if(pig[dst].IDS == BF){
 936             for(int i = 0; i < n; i++){
 937                 int j = scr + i;
 938                 if(j > n) j = j - n;
 939                 if(pig[j].Death) continue;
 940                 if(pig[j].IDF == AP){
 941                     if(Pas_J(dst, j, GA)) return Cal_J(j, j, MA) ? FAIL : SUCCEED;
 942                 }
 943             }
 944             return FAIL;
 945         }
 946     } else {
 947         if(pig[dst].IDF == MP){
 948             for(int i = 0; i < n; i++){
 949                 int j = scr + i;
 950                 if(j > n) j = j - n;
 951                 if(pig[j].Death) continue;
 952                 if(pig[j].IDF == AP){
 953                     if(Pas_J(dst, j, MA)) return Cal_J(j, j, MA) ? FAIL : SUCCEED;
 954                 }
 955             }
 956             return FAIL;
 957         } else if(pig[dst].IDS == BZ){
 958             for(int i = 0; i < n; i++){
 959                 int j = scr + i;
 960                 if(j > n) j = j - n;
 961                 if(pig[j].Death) continue;
 962                 if(pig[j].IDF == AP){
 963                     if(Pas_J(dst, j, MA)) return Cal_J(j, j, MA) ? FAIL : SUCCEED;
 964                 }
 965             }
 966             return FAIL;
 967         } else if(pig[dst].IDS == BF){
 968             for(int i = 0; i < n; i++){
 969                 int j = scr + i;
 970                 if(j > n) j = j - n;
 971                 if(pig[j].Death) continue;
 972                 if(pig[j].IDF == MP || pig[j].IDF == ZP){
 973                     if(Pas_J(dst, j, MA)) return Cal_J(j, j, MA) ? FAIL : SUCCEED;
 974                 }
 975             }
 976             return FAIL;
 977         } else if(pig[dst].IDS == NS){//主猪对类反猪表敌意
 978             if(Pas_J(dst, MP, MA)) return Cal_J(MP, MP, MA) ? FAIL : SUCCEED;
 979             return FAIL;
 980         }
 981     }
 982     return FAIL;
 983 }
 984
 985 inline int Pas_J(int dst, int scr, int State){
 986     if(pig[scr].HC_CNT[J] == 0) return FAIL;
 987     if(State == GA) Gallant(dst, scr);
 988     else Malicious(dst, scr);
 989     pig[scr].Card(J, 1);
 990     return SUCCEED;
 991 }
 992
 993 inline int Cal_N(int Man){
 994     assert(Pas_N(Man));
 995     for(int i = 1; i < n; i++){
 996         int j = Man + i;
 997         if(j > n) j = j - n;
 998         if(pig[j].Death) continue;
 999         if(Cal_J(j, Man, GA) == SUCCEED) continue;
1000         if(Pas_K(0, j) == FAIL){
1001             if(Dec_Health(j, Man) == GAME_OVER) return GAME_OVER;
1002             if(j == MP && pig[Man].IDS == NN) pig[Man].IDS = NS;
1003         }
1004     }
1005     return SUCCEED;
1006 }
1007
1008 inline int Pas_N(int dst){
1009     if(pig[dst].HC_CNT[N] == 0) return FAIL;
1010     pig[dst].Card(N, 1);
1011     return SUCCEED;
1012 }
1013
1014 inline int Cal_W(int Man){
1015     assert(Pas_W(Man));
1016     for(int i = 1; i < n; i++){
1017         int j = Man + i;
1018         if(j > n) j = j - n;
1019         if(pig[j].Death) continue;
1020         if(Cal_J(j, Man, GA) == SUCCEED) continue;
1021         if(Pas_D(j) == FAIL){
1022             if(Dec_Health(j, Man) == GAME_OVER) return GAME_OVER;
1023             if(j == MP && pig[Man].IDS == NN) pig[Man].IDS = NS;
1024         }
1025     }
1026     return SUCCEED;
1027 }
1028
1029 inline int Pas_W(int dst){
1030     if(pig[dst].HC_CNT[W] == 0) return FAIL;
1031     pig[dst].Card(W, 1);
1032     return SUCCEED;
1033 }
1034
1035 inline int Cal_Z(int Man){
1036     return Pas_Z(Man);
1037 }
1038
1039 inline int Pas_Z(int dst){
1040     if(pig[dst].HC_CNT[Z] == 0) return FAIL;
1041     pig[dst].ST_Z = true;
1042     pig[dst].Card(Z, 1);
1043     return SUCCEED;
1044 }

Source Code

原文地址:https://www.cnblogs.com/CreeperLKF/p/9097332.html

时间: 2024-11-02 22:06:00

Luogu2482 [SDOI2010]猪国杀的相关文章

洛谷P2482 [SDOI2010]猪国杀

题目:https://www.luogu.org/problemnew/show/P2482 题目描述 <猪国杀>是一种多猪牌类回合制游戏,一共有三种角色:主猪,忠猪,反猪.每局游戏主猪有且只有一只,忠猪和反猪可以有多只,每只猪扮演一种角色. 游戏目的: 主猪(MP):自己存活的情况下消灭所有的反猪. 忠猪(ZP):不惜一切保护主猪,胜利条件与主猪相同. 反猪(AP):杀死主猪. 游戏过程: 游戏开始时候,每个玩家手里都会有4张牌,且体力上限和初始体力都是4. 开始游戏时,从主猪开始,按照逆时

[SDOI2010]猪国杀

一个能看的题面 : https://mubu.com/doc/2707815814591da4 晚上闲的没事干被Refun忽悠着写猪国杀玩 然后一下子写到现在 浪费了一晚上+一上午 这题一堆肥肠SB的规则总之就是让你用他们的智商玩猪国杀 这是一篇没有任何意义的题解 附上10K的代码 然后那个忽悠我的人一直在嘲讽我写的长TAT #include<map> #include<cstdio> #include<vector> #include<cstring> #

Luogu P2482 [SDOI2010]猪国杀

Pig Country Kill 很古怪的翻译,不过它确实叫猪(Pig)国(Country)杀(Kill). 我们来好好整理一下这道题目.题面虽较长,但内容基本清晰,只是有部分很Pig的操作部分,很容易让第一次看见这道题目的人百思不得其解. 先整理一下这道长长的题面. First:人物 四位玩家,初始四张手牌,血量上限\(4\),初始血量\(4\),会告诉你整个牌堆的牌,每位玩家每个回合从牌堆顶部抽走两张牌,放在自己手牌的右侧.人物分主猪,忠猪,和反猪,主猪只有一只,反猪和忠猪可以有多只,反猪全

bzoj1972: [Sdoi2010]猪国杀 模拟

模拟.认真读题,理清思路. #include<cstdio> #include<list> #include<cstdlib> const int N=10; #define FOR(a,k)for(A k=P[a].begin();k!=P[a].end();++k) using namespace std; int n,m; int HP[N],ST[N]; bool ID[N],Z[N]; list<char> P[N]; typedef list&l

洛谷P2482 猪国杀

题目描述 <猪国杀>是一种多猪牌类回合制游戏,一共有三种角色:主猪,忠猪,反猪.每局游戏主猪有且只有一只,忠猪和反猪可以有多只,每只猪扮演一种角色. 游戏目的: 主猪(MP):自己存活的情况下消灭所有的反猪. 忠猪(ZP):不惜一切保护主猪,胜利条件与主猪相同. 反猪(AP):杀死主猪. 游戏过程: 游戏开始时候,每个玩家手里都会有4张牌,且体力上限和初始体力都是4. 开始游戏时,从主猪开始,按照逆时针方向(数据中就是按照编号从1,2,3..n,1..的顺序)依次行动. 每个玩家自己的回合可以

Yali 19 - 8 - 6 test T2 猪国(pig) 题解

T2 猪国 题?描述 猪国是?个由 \(n\) 个城市组成的国家. 国王意识到了"要致富,先修路"这句话的重要性,它决定?规模修路.不巧的是,猪国的 猪们不太会?程,于是只能请隔壁鸡国的鸡建狂魔来帮忙修路.鸡建狂魔看不起猪,于是随 便建设了 \(m\) 条单向的路.尽管如此,每条路还是产?了或多或少的价值. 路修好了,经济却上不来.国王经过调研,发现了道路的巨?缺陷.具体来说,猪?们?向 感不好,?旦存在若?条路能组成?个环,那么可怜的猪?就有可能在环??绕来绕去,这 样甚?会产?反效

大神刷题表

9月27日 后缀数组:[wikioi3160]最长公共子串 dp:NOIP2001统计单词个数 后缀自动机:[spoj1812]Longest Common Substring II [wikioi3160]最长公共子串 [spoj7258]Lexicographical Substring Search 扫描线+set:[poj2932]Coneology 扫描线+set+树上删边游戏:[FJOI2013]圆形游戏 结论:[bzoj3706][FJ2014集训]反色刷 最小环:[poj1734

联赛之前的题表(已完成)汇总(可能有遗漏)

联赛之前的搞搞(其实是懒得分类) 博弈论 poj3537 poj1704 hdu5996两个插头 HDU1693 Eat the Trees COGS1283. [HNOI2004] 邮递员kdtree板子1941: [Sdoi2010]Hide and Seek旋转卡壳 pj2187凸包 cogs896 bzoj2829 信用卡凸包莫比乌斯反演基础 bzoj 4173 zhao gui lv bzoj 3529 mobiwus bzoj 4407 mobiwus bzoj 2818 mobiw

SDOI2010选做

\(Round1~D1T1\)外星千足虫 \(BSOJ2793\)--高斯消元解异或方程组 简述 有\(n\)个数\(\{a_i\}\) 给出\(m\)个信息,每个信息给出\(\displaystyle{(\sum_{i=1}^m a_{b_i})\bmod 2}\)(\(\{b_i\}\)是\({1,2,\cdots,n}\)的子集) 求最少几次操作即可确定可能取值 Solution \(70pts'\) 给出的信息可以转化为\(\displaystyle{\oplus_{i=1}^m a_{