HDU校赛 【2015.12.26】


估计HDOJ不会挂上去,贴题面记录下吧,指不定哪天账号忘了就GG了。


1001

The Country List

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2516    Accepted Submission(s): 592


Problem Description
As the 2010 World Expo hosted by Shanghai is coming, CC is very honorable to be a volunteer of such an international pageant. His job is to guide the foreign visitors. Although he has a strong desire to be an excellent volunteer, the lack of English makes him annoyed for a long time. 
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.
 

Input
There are multiple test cases.
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.
 

Output
For each case, output the number of hard names in CC’s list.
 

Sample Input
  
  
3 Denmark GERMANY China 4 Aaaa aBaa cBaa cBad
 

Sample Output
  
  
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

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 986    Accepted Submission(s): 217


Problem Description
There is a collector who own many valuable jewels. He has a problem about how to store them. There are M special boxes. Each box has a value. And each of the N jewels has a value too. 
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.
 

Input
There are multiple test cases.
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.
 

Output
Print one integer, indicating the minimal sum of differences.
 

Sample Input
  
  
4 4 1 2 3 4 4 3 2 1 4 4 1 2 3 4 1 1 1 1
 

Sample Output
  
  
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

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1383    Accepted Submission(s): 407


Problem Description
In an apartment, there are N residents. The Internet Service Provider (ISP) wants to connect these residents with N – 1 cables. 
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”.
 

Input
There are multiple test cases. Please process to end of file.
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.
 

Output
For each case, please output the answer in one line.
 

Sample Input
  
  
2 0 1 1 0 3 0 1 5 1 0 3 5 3 0
 

Sample Output
  
  
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

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 652    Accepted Submission(s): 347


Problem Description
You are given two positive integers X and K. Return the K-th smallest positive integer Y, for which the following equation holds: X + Y =X | Y
Where '|' denotes the bitwise OR operator.
 

Input
The first line of the input contains an integer T (T <= 100) which means the number of test cases. 
For each case, there are two integers X and K (1 <= X, K <= 2000000000) in one line.
 

Output
For each case, output one line containing the number Y.
 

Sample Input
  
  
3 5 1 5 5 2000000000 2000000000
 

Sample Output
  
  
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

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 625    Accepted Submission(s): 134


Problem Description
It's really a simple problem. 
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).
 

Input
There is an integer T (0 < T <=50) in the first line, indicating the case number.
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).
 

Output
For each query, output the number of "1" matrix with size by k*k.
 

Sample Input
  
  
2 2 2 01 00 1 2 3 3 010 111 111 1 2 2
 

Sample Output
  
  
1 0 7 2 2
 

题意:给定一个N*N的0-1矩阵和Q次查询,每次查询给出一个k,问你全是1的k*k矩阵有多少个。


思路:正着推出以位置(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

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 181    Accepted Submission(s): 41


Problem Description
This is a 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.
 

Input
There is a positive integer T(1<=T<=50) in the first line, which specifying the number of test cases to follow.
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).
 

Output
Output the maximal value WKC could get.
 

Sample Input
  
  
1 2 2 9 8 7 6
 

Sample Output
  
  
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

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 226    Accepted Submission(s): 80


Problem Description
Learning English is not easy, vocabulary troubles me a lot.
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.
 

Input
T in the first line is case number.
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.
 

Output
For each case, output the top 10 new words I should study, one in a line.
If there are fewer than 10 new words, output all of them.
Output a blank line after each case.
 

Sample Input
  
  
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>
 

Sample Output
  
  
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

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2417    Accepted Submission(s): 624


Problem Description
Like most of the RPG (role play game), “The Magic Tower” is a game about how a warrior saves the princess. 
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.
 

Input
There are several test cases.
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. 
 

Output
For each case, if boss’s HP first turns to be smaller or equal than zero, please print ”Warrior wins”. Otherwise, please print “Warrior loses”. If warrior cannot kill the boss forever, please also print ”Warrior loses”.
 

Sample Input
  
  
W 100 1000 900 100 1000 900 B 100 1000 900 100 1000 900
 

Sample Output
  
  
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;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值