洛谷 题解 P2645 【斯诺克】

吐槽一下这道题:

数据太水了!!!
请注意,这题如果你考虑了犯规的情况,那么你的分数。。。可能会和我一样,只有40分。

也就是说,这是一篇AC不了这道题的题解!!!

现在,我来讲一下这道题的正解:

  1. 两个变量 lesscolor: less 记录剩余颜色为 color 的球的个数,且场上没有颜色比 less 小的球。
  2. 由题意,当场上没有红球时,第单数个球必须是红球
  3. 当场上有红球时,第双数个球必须是彩球,且击打不消耗个数。
  4. less0 时,less = 0, color++;

给出处理某一个人的伪代码:

执行 n 次 {
    记录上次球的颜色
    读入这次球的颜色
    如果 (这次球的颜色为 0) {
        直接给对方加 4 分
    } 否则 如果 (这是第单数个球 并且 红球没有打完) {
        如果 (这次球的颜色不是 1) {
            如果 (这次球的颜色对应的分数比 4 大) {
               给对方加上这次球的颜色对应的分数
            } 否则 {
                给对方加 4 分
            }
        } 否则 {
            给自己加 1 分
            红球个数减 1
            如果 (已经没有红球了) {
                颜色加 1
                该颜色个数置为 1
            }
        }
    } else {
        if ((上次打的不是红球 && 这次打的颜色比应该打的颜色大) || 这次打了红球) {
            如果 (这次球的颜色对应的分数比 4 大) {
               给对方加上这次球的颜色对应的分数
            } 否则 {
                给对方加 4 分
            }
        } else {
            给自己加 这次球的颜色对应的分数 分
            如果 (这个不是红球后面紧随的球) 该球个数减 1;
            如果 (已经没有 color 颜色的球了) {
                颜色加 1
                该颜色个数置为 1
            }
        }
    }
}

最终代码

/*
    Name: Z*** Y* (H***Z*** J***L** Middle School, China) 
    Copyright: 航空信奥
    Author: 航空信奥
    Date: 2018-10-19
    Description: the program that can solve snooker  
*/
#include <queue>
#include <vector>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
using std::max;
using std::min;
using std::cerr;
using std::endl;
using std::sort;
using std::queue;
using std::vector;
using std::priority_queue; 

struct fast_IO {
#define fast_IO_all_DEBUG 0
#define fast_IO_read_DEBUG 0
#define fast_IO_write_DEBUG 0
    
    bool __read_sign_LowThan0; 
    char __read_buf_ch; 
    
    template <typename type> 
    void read(type &res)
    {
        __read_sign_LowThan0 = 0;
        __read_buf_ch = getchar();
        while (__read_buf_ch > '9' || __read_buf_ch < '0') {
            __read_buf_ch = getchar();
            if (__read_buf_ch == '-') {
                __read_sign_LowThan0 = 1;
                __read_buf_ch = getchar();
                break;
            }
        }
        res = (__read_buf_ch & 15); 
        __read_buf_ch = getchar();
        while (__read_buf_ch <= '9' && __read_buf_ch >= '0') {
            res = (res << 3) + (res << 1) + (__read_buf_ch & 15); 
            __read_buf_ch = getchar();
        }
        if (__read_sign_LowThan0) {
            res = ((~res) + 1);
        } 
#if fast_IO_all_DEBUG || fast_IO_read_DEBUG
        printf("[TEST $ read %d $ ]", res);
#endif
    }
} io;

#define read io.read
#define write io.write	

#define passing() fprintf(stderr, "passing line [%d] in function %s.\n", __LINE__, __FUNCTION__)
#define debug(x) cerr << "[debug] " << #x << " = " << x << endl 

#define Max_N (107) 
#define Max_M     
#define Max_K  
#define Max_LogN     
#define Max_LogM      
#define Max_LogK      
  
int n, m, k;
#define P 10007  
int a[Max_N] = {0};
bool used[Max_N] = {false};

#define FILE
int color = 1;
int less = 15;

void doit(int &n, int &mine, int &your)
{
	int t, las;
	for (int i = 1; i <= n; i++) {
		las = t;
		read(t);
		if (!t) {
			your += 4;
		} else if ((i & 1) && color == 1) {
			if (t != 1) {
				if (t > 4) {
					your += t;
				} else {
					your += 4;
				}
			} else {
				mine++;
				less--;
				if (less == 0) {
					color++;
					less = 1;
				}
			}
		} else {
			if ((las != 1 && t > color) || t == 1) {
				if (t > 4) {
					your += t;
				} else {
					your += 4;
				}
			} else {
				mine += t;
				if (las != 1 && color != 1) less--;
				if (less == 0) {
					color++;
					less = 1;
				}
			}
		}
//		printf("ball %d: %d:%d [color = %d eith %d in low]\n", t, mine, your, color, less);
	}
}

int main()
{
#ifdef FILE
	freopen("snooker.in", "r", stdin);
	freopen("snooker.out", "w", stdout);
#endif
    read(n);
    read(m);
    int ansa(0), ansb(0);
    doit(n, ansa, ansb);
    doit(m, ansb, ansa);
    printf("%d %d", ansa, ansb);
    return 0;
}
posted @ 2018-11-02 14:15  航空信奥  阅读(232)  评论(0编辑  收藏  举报