ZOJ Problem Set - 2058 The Archaeologist's Trouble II
Chieh
posted @ 2015年7月30日 14:52
in ZOJ
, 389 阅读
飞机票:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1058
题意:就是给你n行,第i行有i个字符,字符可以是'@','*','?',其中需要确定?的值,根据题目的4中限制,使得得到@最多,或则@最少,输出这个值。
分析:看一下这4种类型可以知道,假设为2行,第一行一个字符,第二行两个,所以我们可以知道无论第一行是什么,第二行都必须是@*或则*@,这样的话我们就知道,假设在第k行,有k个字符,如果第j个字符是@,那么第j-1是*,j+1也是*,然后根据j-1和j+1可以继续第k行剩下的数据。所以,假设第k行都是?,那么如果k%2==0,那么@和*只能平分。反之,设得到@最多为MAX,最少为MIN,那么,MAX多加个1,因为有k/2个*和k/2+1个@,MIN 的话就是k/2个@和k/2+1个*。如果第k行第i个是*,那么可知包含*的话,前面有i个字符,后面有af=k-i+1个字符,那么我们就可以知道MAX和MIN就都得有i/2个和af/2个,因为第i个是*,所以不用管是否奇偶。反之,一样MAX和MIN就都得有i/2个和af/2个,但是这里就得再考虑,如果i是奇数,那么我们得再加个1,因为i也是,如果af是奇数,同理,但是我们这里多记了1次i这个位置,所以都要减1。最后输出MAX和MIN就好了,啪啪啪就可以AC了
/* Author:Chieh Because Of Coding */ #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #include <stack> #define LL long long #define INF 1e9 #define EPS 1e-9 using namespace std; const int maxn=123; char ch[maxn]; int n; int MAX,MIN; void init() { MAX=0; MIN=0; for(int i=1; i<=n; i++) { scanf("%s",ch+1); bool flag=1; for(int j=1; j<=i; j++) { int af=i-j+1; if(ch[j]=='*') { flag=0; } if(ch[j]=='@') { if(j%2==1) { MAX++; MIN++; } if(af%2==1) { MAX++; MIN++; } MAX-=1; MIN-=1; flag=0; } if(!flag) { MAX+=j/2; MIN+=j/2; MAX+=af/2; MIN+=af/2; break; } } if(flag) { MAX+=i/2; MIN+=i/2; if(i%2==1)MAX++; } } } void play() { printf("%d %d\n",MAX,MIN); } int main() { while(scanf("%d",&n)&&n>0) { init(); play(); } // cout << "Hello world!" << endl; return 0; }