2017中国大学生程序设计竞赛 - 女生专场

链接:http://acm.hdu.edu.cn/showproblem.php?pid=6023
hdu 6023 Automatic Judge

Problem Description
Welcome to HDU to take part in the second CCPC girls’ competition!
A new automatic judge system is used for this competition. During the five-hour contest time, you can submit your code to the system, then the judge will reply you. Here is a list of the judge’s replies and their meaning:

  1. Accepted(AC): Yes, your program is correct. You did a good job!

  2. PresentationError(PE) : Your program’s output format is not exactly the same as required by the problem, although the output is correct. This usually means the existence of omitted or extra blank characters (white spaces, tab characters and/or new line characters) between any two non-blank characters, and/or blank lines (a line consisting of only blank characters) between any two non-blank lines. Trailing blank characters at the end of each line and trailing blank lines at the of output are not considered format errors. Check the output for spaces, blank lines, etc. against the problem’s output specification.

  3. WrongAnswer(WA) : Correct solution not reached for the inputs. The inputs and outputs that we use to test the programs are not public (it is recomendable to get accustomed to a true contest dynamic :-)

  4. RuntimeError(RE) : Your program failed during the execution and you will receive the hints for the reasons.

  5. TimeLimitExceeded(TLE) : Your program tried to run during too much time.

  6. MemoryLimitExceeded(MLE): Your program tried to use more memory than the judge default settings.

  7. OutputLimitExceeded(OLE): Your program tried to write too much information. This usually occurs if it goes into a infinite loop.

  8. CompilationError(CE): The compiler fails to compile your program. Warning messages are not considered errors. Click on the judge’s reply to see the warning and error messages produced by the compiler.

For each submission, if it is the first time that the judge returns “AC” on this problem, then it means you have passed this problem, and the current time will be added to the penalty of your team. In addition, every time you pass a problem, each unsuccessful try for that problem before is counted as 20 minutes penalty, it should also be added to the penalty of your team.
Now given the number of problems in the contest and the submission records of a team. Please write a program to calculate the number of problems the team passed and their penalty.

Input
The first line of the input contains an integer T(1≤T≤20), denoting the number of test cases.
In each test case, there are two integers n(1≤n≤13) and m(1≤m≤100) in the first line, denoting the number of problems and the number of submissions of a team. Problems are labeled by 1001, 1002, …, 1000+n.
In the following m lines, each line contains an integer x(1001≤x≤1000+n) and two strings t(00:00≤t≤05:00) and s, denoting the team submits problem x at time t, and the result is s. t is in the format of HH:MM, while s is in the set {AC, PE, WA, RE, TLE, MLE, OLE}. The team is so cautious that they never submit a CE code. It is guaranteed that all the t in the input is in ascending order and every t is unique.

Output
For each test case, print a single line containing two integers A and B, denoting the number of problems the team passed and the penalty.

Sample Input
1
3 5
1002 00:02 AC
1003 00:05 WA
1003 00:06 WA
1003 00:07 AC
1002 04:59 AC

Sample Output
2 49

分析:模拟

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define mem(a,n) memset(a,n,sizeof(a))
typedef long long LL;
const int N=20;
int a[N],cnt[N];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        mem(cnt,0);
        mem(a,0);
        int n,m,ans=0,time=0;
        int id,h,mi;
        char flag[10];
        scanf("%d%d",&n,&m);
        for(int i=0;i<m;i++)
        {
            scanf("%d %d:%d %s",&id,&h,&mi,flag);
            id-=1000;
            if(!a[id]&&!strcmp(flag,"AC"))
            {
                ans++;
                a[id]=1;
                time+=(cnt[id]*20+60*h+mi);
            }
            else cnt[id]++;
        }
        printf("%d %d\n",ans,time);
    }
    return 0;
}

链接 :http://acm.hdu.edu.cn/showproblem.php?pid=6024
hdu 6024 Building Shops

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1197 Accepted Submission(s): 459

Problem Description
HDU’s n cla***ooms are on a line ,which can be considered as a number line. Each cla***oom has a coordinate. Now Little Q wants to build several candy shops in these n cla***ooms.

The total cost consists of two parts. Building a candy shop at cla***oom i would have some cost ci. For every cla***oom P without any candy shop, then the distance between P and the rightmost cla***oom with a candy shop on P’s left side would be included in the cost too. Obviously, if there is a cla***oom without any candy shop, there must be a candy shop on its left side.

Now Little Q wants to know how to build the candy shops with the minimal cost. Please write a program to help him.

Input
The input contains several test cases, no more than 10 test cases.
In each test case, the first line contains an integer n(1≤n≤3000), denoting the number of the cla***ooms.
In the following n lines, each line contains two integers xi,ci(−109≤xi,ci≤109), denoting the coordinate of the i-th cla***oom and the cost of building a candy shop in it.
There are no two cla***ooms having same coordinate.

Output
For each test case, print a single line containing an integer, denoting the minimal cost.

Sample Input
3
1 2
2 3
3 4
4
1 7
3 1
5 10
6 1

Sample Output
5
11

题意:
有n个教室,现在想在这n个教室中建一些超市,问你最少费用为多少?
费用分为两种:
1:在第i个教室建超市,费用因为ci
2:没有建超市的教室的费用为它和它左边最接近的超市的坐标之间的距离
之前写重现赛的时候一直超时,都没想到用DP,理解后补上

分析:每个教室有两种决策,建超市或者不建 类似与01背包问题
题目中n的最大值为3000,那么可以用O(n^2)的算法,于是就可以用DP写

设dp[i][0]为 不建第i个教室的最少费用, dp[i][1]为 建第i个教室的最少费用
可以知道 dp[i][1]=max(dp[i-1][0],dp[i-1])+p[x].c;
dp[i][0]= 枚举i到i的左边的所有教室的距离,取其中的最小值
枚举的时候从第i-1个教室一直枚举到第j个教室

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define mem(a,n) memset(a,n,sizeof(a))
typedef long long LL;
const int N=3e3+5;
const int INF=0x3f3f3f3f;
struct Node
{
    LL x,c;
    bool operator < (const Node& m)const
    {
        return x<m.x;
    }
} p[N];
LL dp[N][2];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=0; i<n; i++)
        {
            scanf("%lld%lld",&p[i].x,&p[i].c);
            dp[i][0]=INF;
        }
        sort(p,p+n);
        dp[0][1]=p[0].c;
        for(int i=1; i<n; i++)
        {
            dp[i][1]=min(dp[i-1][0],dp[i-1][1])+p[i].c;
            LL sum=0;
            for(int j=i-1; j>=0; j--)
            {
                sum+=(i-j)*(p[j+1].x-p[j].x);
                dp[i][0]=min(dp[i][0],dp[j][1]+sum);///第二项中表示第j个到第i个教室之间不能建超市
            }
        }
        LL ans=min(dp[n-1][0],dp[n-1][1]);
        printf("%lld\n",ans);
    }
    return 0;
}

链接: http://acm.hdu.edu.cn/showproblem.php?pid=6025
hdu 6025 Coprime Sequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1074 Accepted Submission(s): 537

Problem Description
Do you know what is called Coprime Sequence''? That is a sequence consists of n positive integers, and the GCD (Greatest Common Divisor) of them is equal to 1.
Coprime Sequence” is easy to find because of its restriction. But we can try to maximize the GCD of these integers by removing exactly one integer. Now given a sequence, please maximize the GCD of its elements.

Input
The first line of the input contains an integer T(1≤T≤10), denoting the number of test cases.
In each test case, there is an integer n(3≤n≤100000) in the first line, denoting the number of integers in the sequence.
Then the following line consists of n integers a1,a2,…,an(1≤ai≤109), denoting the elements in the sequence.

Output
For each test case, print a single line containing a single integer, denoting the maximum GCD.

Sample Input
3
3
1 1 1
5
2 2 2 3 2
4
1 2 4 8

Sample Output
1
2
2

题意:给定长度为n([3,10^5])的序列,序列元素均为正整数且不大于10^9,问删除其中一个数,让整个序列的公因数最大,最大为多少?

分析:删除某个数就等价于求最大公因数时这个数不参与
n为[3,10^9],那么可以从前往后枚举依次求出各个连续子序列的最大公因数,同理,从后往前求一次,然后取其中的最大公因数

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long LL;
const int N=1e5+5;
int a[N],L[N],R[N];
int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=0; i<n; i++)
            scanf("%d",&a[i]);
        L[0]=a[0],R[n-1]=a[n-1];
        for(int i=1; i<n-1; i++)
            L[i]=gcd(L[i-1],a[i]);
        for(int i=n-2; i>=0; i--)
            R[i]=gcd(R[i+1],a[i]);
        int ans=max(L[n-2],R[1]);
        for(int i=1; i<n-1; i++)
            ans=max(ans,gcd(L[i-1],R[i+1]));
        printf("%d\n",ans);
    }
    return 0;
}

链接 : http://acm.hdu.edu.cn/showproblem.php?pid=6027
hdu 6027 Easy Summation

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1351 Accepted Submission(s): 555

Problem Description
You are encountered with a traditional problem concerning the sums of powers.
Given two integers n and k. Let f(i)=ik, please evaluate the sum f(1)+f(2)+…+f(n). The problem is simple as it looks, apart from the value of n in this question is quite large.
Can you figure the answer out? Since the answer may be too large, please output the answer modulo 109+7.

Input
The first line of the input contains an integer T(1≤T≤20), denoting the number of test cases.
Each of the following T lines contains two integers n(1≤n≤10000) and k(0≤k≤5).

Output
For each test case, print a single line containing an integer modulo 109+7.

Sample Input
3
2 5
4 2
4 1

Sample Output
33
30
10
分析:n最大为10^4,遍历一遍直接用快速幂计算

如果n大于10^6,甚至更大,这种方法就不行了,好像大佬有一个拉格朗日插值的计算公式,时间复杂度和k有关,而不是和n有关,用这个公式好像直接把n套进去就可以了 。。。 有时间再看吧。。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
#define mem(a,n) memset(a,n,sizeof(a))
typedef  long long LL;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const int N=1e4+5;
LL pow_mod(LL a,LL b,LL mod)
{
    LL ans=1;
    a%=mod;
    while(b)
    {
        if(b&1) ans=ans*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return ans;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,k;
        scanf("%d%d",&n,&k);
        LL sum=0;
        for(int i=1;i<=n;i++)
        {
            sum=(sum+pow_mod(i,k,mod))%mod;
        }
        printf("%lld\n",sum);
    }
    return 0;
}

链接: http://acm.hdu.edu.cn/showproblem.php?pid=6029
hdu 6029 Graph Theory

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 631 Accepted Submission(s): 313

Problem Description
Little Q loves playing with different kinds of graphs very much. One day he thought about an interesting category of graphs called “Cool Graph”, which are generated in the following way:
Let the set of vertices be {1, 2, 3, …, n}. You have to consider every vertice from left to right (i.e. from vertice 2 to n). At vertice i, you must make one of the following two decisions:
(1) Add edges between this vertex and all the previous vertices (i.e. from vertex 1 to i−1).
(2) Not add any edge between this vertex and any of the previous vertices.
In the mathematical discipline of graph theory, a matching in a graph is a set of edges without common vertices. A perfect matching is a matching that each vertice is covered by an edge in the set.
Now Little Q is interested in checking whether a ”Cool Graph” has perfect matching. Please write a program to help him.

Input
The first line of the input contains an integer T(1≤T≤50), denoting the number of test cases.
In each test case, there is an integer n(2≤n≤100000) in the first line, denoting the number of vertices of the graph.
The following line contains n−1 integers a2,a3,…,an(1≤ai≤2), denoting the decision on each vertice.

Output
For each test case, output a string in the first line. If the graph has perfect matching, output ”Yes”, otherwise output ”No”.

Sample Input
3
2
1
2
2
4
1 1 2

Sample Output
Yes
No
No

题意
有N个点,然后告诉你两个规则组成一个图。
判断图是否可以组成完全二分图。

完全二分图含义为挑一些边,边的顶点没有重复的,且恰好覆盖所有顶点。

规则1是i节点与左边所有节点没边。
规则2是i节点与右边所有节点没边。

思路

由于规则固定,所以图固定了。
但是由于节点可能太多,我们不能模拟算出图,然后使用对应算法是否是匹配的。

规则有个特点就特点就是是否和左边的所有节点有边。
所以这道题的突破口就在这里,我们从右逆着来推这道题。

1.节点数为奇数,则不存在完全二分匹配。
2.从右到左扫描。
3.累计规则1的个数,遇到规则2则个数减一。
4.不够减则不存在完全二分匹配。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long LL;
const int N=1e5+5;
int a[N];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<n;i++)
            scanf("%d",&a[i]);
        if(n&1)
        {
            puts("No");
            continue;
        }
        int cnt=0,flag=0;
        for(int i=n-1;i>=1;i--)
        {
            if(a[i]==1) cnt++;
            else cnt--;
            if(cnt<0)
            {
                flag=1;
                break;
            }
        }
        printf("%s\n",flag?"No":"Yes");
    }
    return 0;
}

 

上一篇:A. Odd Set


下一篇:D-Determine the Photo Positio