估计HDOJ不会挂上去,贴题面记录下吧,指不定哪天账号忘了就GG了。
1001
The Country List
Some countries’ names look so similar that he can’t distinguish them. Such as: Albania and Algeria. If two countries’ names have the same length and there are more than 2 same letters in the same position of each word, CC cannot distinguish them. For example: Albania and AlgerIa have the same length 7, and their first, second, sixth and seventh letters are same. So CC can’t distinguish them.
Now he has received a name list of countries, please tell him how many words he cannot distinguish. Note that comparisons between letters are case-insensitive.
Each case begins with an integer n (0 < n < 100) indicating the number of countries in the list.
The next n lines each contain a country’s name consisted by ‘a’ ~ ‘z’ or ‘A’ ~ ‘Z’.
Length of each word will not exceed 20.
You can assume that no name will show up twice in the list.
3 Denmark GERMANY China 4 Aaaa aBaa cBaa cBad
2 4
题意:给你n个城市名(字符串),若两个城市名长度相等且有超过3个字符相同,则它们是不能被识别的。问你有多少个城市名是不能识别的。
思路:直接模拟。
AC代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MAXN (100+10)
#define MAXM (100000)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
#define PI acos(-1.0)
using namespace std;
char str[110][30];
int vis[110];
bool judge(char *a, char *b)
{
int la = strlen(a);
int lb = strlen(b);
if(la == lb)
{
int cnt = 0;
for(int i = 0; i < la; i++)
{
if(a[i] == b[i])
cnt++;
}
return cnt > 2;
}
return false;
}
int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
for(int i = 0; i < n; i++)
{
Rs(str[i]);
int len = strlen(str[i]);
for(int j = 0; j < len; j++)
{
if(str[i][j] >= 'a' && str[i][j] <= 'z')
str[i][j] -= 32;
}
}
int ans = 0;
CLR(vis, 0);
for(int i = 0; i < n; i++)
{
for(int j = i+1; j < n; j++)
{
if(judge(str[i], str[j]))
vis[i] = vis[j] = 1;
}
}
for(int i = 0; i < n; i++)
ans += vis[i];
Pi(ans);
}
return 0;
}
1003
The collector’s puzzle
The collector wants to store every jewel in one of the boxs while minimizing the sum of difference value.
The difference value between a jewel and a box is: |a[i] - b[j]|, a[i] indicates the value of i-th jewel, b[j] indicates the value of j-th box.
Note that a box can store more than one jewel.
Now the collector turns to you for helping him to compute the minimal sum of differences.
For each case, the first line has two integers N, M (1<=N, M<=100000).
The second line has N integers, indicating the N jewels’ values.
The third line have M integers, indicating the M boxes’ values.
Each value is no more than 10000.
4 4 1 2 3 4 4 3 2 1 4 4 1 2 3 4 1 1 1 1
0 6
题意:给定N个宝石和M个盒子,每个盒子可以装多个宝石。宝石装进盒子的代价为二者价值之差。现在给出所有宝石和盒子的价值,问把N个宝石全部装进盒子的最小代价。
思路:排序去重处理下M个盒子,二分查找就可以了,注意和左右比较。
时间复杂度O(NlogN)。
AC代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MAXN (100000+10)
#define MAXM (100000)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
#define PI acos(-1.0)
using namespace std;
int a[MAXN], b[MAXN];
int main()
{
int N, M;
while(scanf("%d%d", &N, &M) != EOF)
{
for(int i = 1; i <= N; i++)
Ri(b[i]);
for(int i = 1; i <= M; i++)
Ri(a[i]);
sort(a, a+M+1);
int R = 2;
for(int i = 2; i <= M; i++)
if(a[i] != a[i-1])
a[R++] = a[i];
sort(a, a+R);
int ans = 0;
for(int i = 1; i <= N; i++)
{
int p = lower_bound(a, a+R-1, b[i]) - a;
int Min = abs(a[p]-b[i]);
if(p > 1)
Min = min(Min, abs(a[p-1]-b[i]));
else if(p < R-1)
Min = min(Min, abs(a[p+1]-b[i]));
ans += Min;
}
Pi(ans);
}
return 0;
}
1004
Happy Value
However, the friendships of the residents are different. There is a “Happy Value” indicating the degrees of a pair of residents. The higher “Happy Value” is, the friendlier a pair of residents is. So the ISP wants to choose a connecting plan to make the highest sum of “Happy Values”.
For each case, the first line contains only one integer N (2<=N<=100), indicating the number of the residents.
Then N lines follow. Each line contains N integers. Each integer H ij(0<=H ij<=10000) in i th row and j th column indicates that i th resident have a “Happy Value” H ijwith j th resident. And H ij(i!=j) is equal to H ji. H ij(i=j) is always 0.
2 0 1 1 0 3 0 1 5 1 0 3 5 3 0
1 8
题意:给定一个n*n矩阵,其中(i, j)位置的元素表示i点和j点连通的价值,问用n-1条边连通所有点的最大价值。
思路:建图后,跑一次最大生成树即可。
AC代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MAXN (100+10)
#define MAXM (100000)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) mempre(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
#define PI acos(-1.0)
using namespace std;
struct Edge{
int from, to, val;
};
Edge edge[100000+10];
bool cmp(Edge a, Edge b){
return a.val > b.val;
}
int pre[110];
int find(int p)
{
int child = p;
int t;
while(p != pre[p])
p = pre[p];
while(child != p)
{
t = pre[child];
pre[child] = p;
child = t;
}
return p;
}
void merge(int x,int y)
{
int fx = find(x);
int fy = find(y);
if(fx != fy)
pre[fx] = fy;
}
int Map[110][110];
int main()
{
int n;
while(Ri(n) != EOF)
{
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
Ri(Map[i][j]);
}
int top = 0;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j < i; j++)
{
edge[top].from = i;
edge[top].to = j;
edge[top].val = Map[i][j];
top++;
}
}
sort(edge, edge+top, cmp);
int ans = 0;
for(int i = 1; i <= n; i++)
pre[i] = i;
for(int i = 0; i < top; i++)
{
if(find(edge[i].from) != find(edge[i].to))
{
ans += edge[i].val;
merge(edge[i].from, edge[i].to);
}
}
Pi(ans);
}
return 0;
}
1005
Bitwise Equations
Where '|' denotes the bitwise OR operator.
For each case, there are two integers X and K (1 <= X, K <= 2000000000) in one line.
3 5 1 5 5 2000000000 2000000000
2 18 16383165351936
题意:给你一个数X和K,问你第K小的数Y使得X + Y = X | Y。
思路:显然对于X,若它的二进制位为0,那么Y对应的二进制位可以填0和1;反之Y对应的二进制位只能填0。
因此,只需要预处理X二进制的前i位的合法填数方案vnum[i],这个过程中借助了num[i]——前i位不同的组合数,可能头一位是0。统计前缀和sum。接下来,一步步找好了,填好Y的二进制位,求出Y就可以了。
后来发现自己一开始就想复杂了。。。
AC代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MAXN (100+10)
#define MAXM (100000)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) mempre(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
#define PI acos(-1.0)
using namespace std;
char bit[100], Y[100];
LL num[100], vnum[100], sum[100];
LL Pow(int a, int n)
{
LL ans = 1;
while(n)
{
ans *= a;
n--;
}
return ans;
}
int main()
{
int t; Ri(t);
W(t)
{
LL N, K;
Rl(N); Rl(K);
for(int i = 0; i < 63; i++)
{
bit[i] = '0' + (N & 1LL);
N >>= 1;
}
bit[63] = '\0';
int pre = -1;
if(bit[0] == '0')
{
num[0] = 2;
vnum[0] = 1;
pre = 0;
}
else
{
num[0] = 1;
vnum[0] = 0;
}
sum[0] = vnum[0];
for(int i = 1; i < 63; i++)
{
if(bit[i] == '0')
{
if(pre == -1)
vnum[i] = 1;
else
vnum[i] = 2 * vnum[pre];
num[i] = num[i-1] * 2;
pre = i;
}
else
{
vnum[i] = 0;
num[i] = num[i-1];
}
sum[i] = sum[i-1] + vnum[i];
//printf("%d\n", sum[i]);
}
for(int i = 0; i < 63; i++)
Y[i] = '0';
Y[63] = '\0';
while(K)
{
int pos = 0; bool flag = false;
for(int i = 0; i < 63; i++)
{
if(sum[i] >= K)
{
pos = i;
if(sum[i] == K)
flag = true;
break;
}
}
Y[pos] = '0' + 1;
K -= vnum[pos];
}
LL ans = 0;
for(int i = 0; i < 63; i++)
ans += Pow(2, i) * (Y[i] - '0');
Pl(ans);
}
return 0;
}
1006
01 Matrix
Given a "01" matrix with size by n*n (the matrix size is n*n and only contain "0" or "1" in each grid), please count the number of "1" matrix with size by k*k (the matrix size is k*k and only contain "1" in each grid).
Each test case begins with two numbers n and m (0<n, m<=1000), specifying the size of matrix and the query number.
Then n lines follow and each line contains n chars ("0" or "1").
Then m lines follow, each lines contains a number k (0<k<=n).
2 2 2 01 00 1 2 3 3 010 111 111 1 2 2
1 0 7 2 2
思路:正着推出以位置(i, j)结尾的三个信息
一、row[i][j] —— 第i行以(i, j)结尾的连续1的个数。
状态转移
1,Map[i][j] = 1, row[i][j] = row[i-1][j] + 1;
2,Map[i][j] = 0, row[i][j] = 0;
二、cul[i][j] —— 第j列以(i, j)结尾的连续1的个数。
状态转移
1,Map[i][j] = 1, cul[i][j] = cul[i][j-1] + 1;
2,Map[i][j] = 0, cul[i][j] = 0;
三、low[i][j] —— 以(i, j)为右下角的全是1的矩阵的最小尺寸(假设为k,那么尺寸>k的矩阵是不存在的)
状态转移
1,Map[i][j] = 1, low[i][j] = min(low[i-1][j-1]+1, min(row[i][j], cul[i][j]));
2,Map[i][j] = 0, low[i][j] = 0;
这样,考虑每个位置(i, j)对结果的贡献,只统计到low[i][j]即可,对应的>low[i][j]的部分不考虑的。
为了方便,在k=1时,对所有矩阵中的1,在其对应区间累加1,。而对后面的统计,为了不计算>low[i][j]的部分,在对应区间累加-1。统计时求和就好了。用树状数组方便些吧。
时间复杂度O(T*n^2*log(n))。
AC代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MAXN (1000+10)
#define MAXM (100000)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
#define PI acos(-1.0)
using namespace std;
int C[MAXN];
int lowbit(int x){
return x & (-x);
}
void Update(int x, int d, int n)
{
while(x <= n)
{
C[x] += d;
x += lowbit(x);
}
}
int Sum(int x)
{
int s = 0;
while(x > 0)
{
s += C[x];
x -= lowbit(x);
}
return s;
}
int Map[MAXN][MAXN];
int row[MAXN][MAXN], cul[MAXN][MAXN], low[MAXN][MAXN];
int ans[MAXN];
void init(int n)
{
CLR(row, 0); CLR(cul, 0); CLR(C, 0); CLR(low, 0);
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if(Map[i][j] == 0) continue;
Update(1, 1, n);
row[i][j] = row[i-1][j] + 1;
cul[i][j] = cul[i][j-1] + 1;
low[i][j] = min(low[i-1][j-1]+1, min(row[i][j], cul[i][j]));
Update(low[i][j]+1, -1, n);
}
}
for(int i = 1; i <= n; i++)
ans[i] = Sum(i);
}
char str[MAXN];
int main()
{
int t; Ri(t);
W(t)
{
int N, Q;
Ri(N); Ri(Q);
for(int i = 1; i <= N; i++)
{
Rs(str);
int len = strlen(str);
for(int j = 0; j < len; j++)
Map[i][j+1] = str[j] - '0';
}
init(N);
while(Q--)
{
int k; Ri(k);
Pi(ans[k]);
}
}
return 0;
}
1007
Pick Game
On a n*m matrix, each gird has a value. The player could only choose the gird that is adjacent to at least two empty girds (A grid outside the matrix also regard as empty). Adjacent means two girds share a common edge. If one play chooses one gird, he will get the value and the gird will be empty. They play in turn.
One day, WKC plays this game with ZJS.
Both of them are clever students, so they will choose the best strategy.
WKC plays first, and he wants to know the maximal value he could get.
Each test case begins with two numbers n and m ( 2 <= n, m <= 5 ).
Then n lines follow and each lines with m numbers V ij (0< V ij <=1000).
1 2 2 9 8 7 6
16
题意:给你一个n*m的格子,每个格子都有一个元素。每次取数的条件是该元素周围至少有两个空位置(取过的和边界都算)。现在两个人轮流去,假设两个人都足够聪明,问你先手可以得到的最大价值。
思路:状压dp。对n*m个格子压缩状态后,dp[state] 表示 在state情况下先手取数可以获取的最大价值。
每次记忆化更新时 max(sum - dp[nextstate])即可。
AC代码:还可以优化写,先存下每个格子的状态就好了。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#include <string>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MAXN (10000+10)
#define MAXM (100000)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
#define PI acos(-1.0)
using namespace std;
int Map[5][5];
int Move[4][2] = {0,1, 0,-1, 1,0, -1,0};
int n, m;
int num[5][5];
bool judge(int x, int y){
return x >= 0 && x < n && y >= 0 && y < m;
}
bool Check(int S, int x, int y){
return (S & (1<<(x*m+y))) && num[x][y] <= 2;
}
void Update(int x, int y, int op)
{
for(int i = 0; i < 4; i++)
{
int xx = x + Move[i][0];
int yy = y + Move[i][1];
if(!judge(xx, yy)) continue;
if(op == 0)
num[xx][yy]--;
else if(op == 1)
num[xx][yy]++;
}
}
map<int, int> dp;
int DFS(int S, int sum)
{
if(dp.find(S) != dp.end()) return dp[S];
int ans = 0;
//dp[S] = 0;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
if(Check(S, i, j))
{
Update(i, j, 0);
ans = max(ans, sum-DFS(S^(1<<(i*m+j)), sum-Map[i][j]));
Update(i, j, 1);
}
}
}
dp[S] = ans;
return ans;
}
int main()
{
int t; Ri(t);
W(t)
{
Ri(n); Ri(m);
int sum = 0, S = 0;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
Ri(Map[i][j]); sum += Map[i][j]; num[i][j] = 0;
for(int k = 0; k < 4; k++)
{
int xx = i + Move[k][0];
int yy = j + Move[k][1];
if(judge(xx, yy))
num[i][j]++;
}
S |= (1<<(i*m+j));
}
}
dp.clear(); dp[0] = 0;
Pi(DFS(S, sum));
}
return 0;
}
1008
Study Words
One day an idea came up to me: I download an article every day, choose the 10 most popular new words to study.
A word's popularity is calculated by the number of its occurrences.
Sometimes two or more words have the same occurrences, and then the word with a smaller lexicographic has a higher popularity.
Each case has two parts.
<oldwords>
...
</oldwords>
<article>
...
</article>
Between <oldwords> and </oldwords> are some old words (no more than 10000) I have already learned, that is, I don't need to learn them any more.
Words between <oldwords> and </oldwords> contain letters ('a'~'z','A'~'Z') only, separated by blank characters (' ','\n' or '\t').
Between <article> and </article> is an article (contains fewer than 1000000 characters).
Only continuous letters ('a'~'z','A'~'Z') make up a word. Thus words like "don't" are regarded as two words "don" and "t”, that's OK.
Treat the uppercase as lowercase, so "Thanks" equals to "thanks". No words will be longer than 100.
As the article is downloaded from the internet, it may contain some Chinese words, which I don't need to study.
If there are fewer than 10 new words, output all of them.
Output a blank line after each case.
2 <oldwords> how aRe you </oldwords> <article> --How old are you? --Twenty. </article> <oldwords> google cn huluobo net i </oldwords> <article> 文章内容: I love google,dropbox,firefox very much. Everyday I open my computer , open firefox , and enjoy surfing on the inter- net. But these days it's strange that searching "huluobo" is unavail- able. What's wrong with "huluobo"? </article>
old twenty firefox open s able and but computer days dropbox enjoy
感觉这才是最水的题目。。。
AC代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#include <string>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MAXN (10000+10)
#define MAXM (100000)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
#define PI acos(-1.0)
using namespace std;
struct Node{
char ss[110];
int time;
};
Node num[MAXN];
bool cmp(Node a, Node b)
{
if(a.time != b.time)
return a.time > b.time;
else
return strcmp(a.ss, b.ss) < 0;
}
map<string, int> fp;
char str[1000001];
char s[110];
int main()
{
int t; Ri(t);
getchar();
W(t)
{
fp.clear();
scanf("%s", str); int top = 0;
while(gets(str), strcmp(str, "</oldwords>"))
{
int len = strlen(str);
for(int i = 0; i < len; i++)
{
if(str[i] >= 'A' && str[i] <= 'Z')
str[i] += 32;
if(str[i] >= 'a' && str[i] <= 'z')
s[top++] = str[i];
else
{
if(top)
{
s[top] = '\0';//Ps(s);
fp[s] = -1;
}
top = 0;
}
}
if(top)
{
s[top] = '\0';
//Ps(s);
fp[s] = -1;
top = 0;
}
}
scanf("%s", str); int n = 0;
while(gets(str), strcmp(str, "</article>"))
{
int len = strlen(str);
for(int i = 0; i < len; i++)
{
if(str[i] >= 'A' && str[i] <= 'Z')
str[i] += 32;
if(str[i] >= 'a' && str[i] <= 'z')
s[top++] = str[i];
else
{
if(top)
{
s[top] = '\0';//Ps(s);
if(fp[s] != -1)
{
if(fp[s] == 0)
{
strcpy(num[n].ss, s);
n++;
}
fp[s]++;
}
}
top = 0;
}
}
if(top)
{
s[top] = '\0';
if(fp[s] != -1)
{
if(fp[s] == 0)
{
strcpy(num[n].ss, s);
n++;
}
fp[s]++;
}
top = 0;
}
}
for(int i = 0; i < n; i++)
num[i].time = fp[num[i].ss];
sort(num, num+n, cmp);
for(int i = 0; i < min(10, n); i++)
Ps(num[i].ss);
printf("\n");
}
return 0;
}
1009
The Magic Tower
After killing lots of monsters, the warrior has climbed up the top of the magic tower. There is a boss in front of him. The warrior must kill the boss to save the princess.
Now, the warrior wants you to tell him if he can save the princess.
For each case, the first line is a character, “W” or “B”, indicating that who begins to attack first, ”W” for warrior and ”B” for boss. They attack each other in turn.
The second line contains three integers, W_HP, W_ATK and W_DEF. (1<=W_HP<=10000, 0<=W_ATK, W_DEF<=65535), indicating warrior’s life point, attack value and defense value.
The third line contains three integers, B_HP, B_ATK and B_DEF. (1<=B_HP<=10000, 0<=B_ATK, B_DEF<=65535), indicating boss’s life point, attack value and defense value.
Note: warrior can make a damage of (W_ATK-B_DEF) to boss if (W_ATK-B_DEF) bigger than zero, otherwise no damage. Also, boss can make a damage of (B_ATK-W_DEF) to warrior if (B_ATK-W_DEF) bigger than zero, otherwise no damage.
W 100 1000 900 100 1000 900 B 100 1000 900 100 1000 900
Warrior wins Warrior loses
题意:给定W和B的血量,攻击力和防御力,并给出谁先攻击,问谁可以胜。若W不能杀死B,算W输。
很水的题吧,分类讨论。
AC代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MAXN (100+10)
#define MAXM (100000)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
#define PI acos(-1.0)
using namespace std;
int main()
{
char op[2];
int wh, wa, wd;
int bh, ba, bd;
while(Rs(op) != EOF)
{
Ri(wh); Ri(wa); Ri(wd);
Ri(bh); Ri(ba); Ri(bd);
int wt = INF, bt = INF;
if(wa > bd)
{
wt = bh / (wa - bd) + 1;
if(bh % (wa - bd) == 0)
wt--;
}
if(ba > wd)
{
bt = wh / (ba - wd) + 1;
if(wh % (ba - wd) == 0)
bt--;
}
//printf("%d %d\n", wt, bt);
if(op[0] == 'W')
{
if(wt == INF && bt == INF)
printf("Warrior loses\n");
else if(wt == INF)
printf("Warrior loses\n");
else if(bt == INF)
printf("Warrior wins\n");
else if(wt <= bt)
printf("Warrior wins\n");
else
printf("Warrior loses\n");
}
else
{
if(wt == INF && bt == INF)
printf("Warrior loses\n");
else if(wt == INF)
printf("Warrior loses\n");
else if(bt == INF)
printf("Warrior wins\n");
else if(wt < bt)
printf("Warrior wins\n");
else
printf("Warrior loses\n");
}
}
return 0;
}