17杭州女子专场赛

 


湘潭赛前和队友去女子赛重现打了下,因为对女生的题目好奇吧,前三个小时A了6道题,但是之前是看过题目的,如果能女装去现场赛的话A6道题可以银了,233,后两小时不想做了三个就出去骑红包车了。=-=

Automatic Judge

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

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(1T20), denoting the number of test cases.
In each test case, there are two integers n(1n13) and m(1m100) 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(1001x1000+n) and two strings t(00:00t05:00) and s, denoting the team submits problem xat time t, and the result is st 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

 

 

第一题水题:坑点在如果这道题一直WA,没有AC的话是不加罚时的,Orz,我这里开一个WA次数的数组,一个标记数组,如果这个题一直没A为0状态,就减去次数*WA的时间。

 

#include <bits/stdc++.h>
using namespace std;
int flag[1050];
int flag2[1050];
int c[1050];
string id;
//int a[1050][];

int main()
{
//    freopen("in.txt","r",stdin);
    int sum;
    int sum1;
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int num;
        memset(flag,0,sizeof(flag));
        memset(c,0,sizeof(c));
        sum = 0;
        sum1 = 0;
        int n,m;
        int cnt = 0;
        scanf("%d%d",&n,&m);
        while(m--)
        {

            int h,mi;
            char res[50];

            scanf("%d %d:%d %s",&num,&h,&mi,res);
            int time = mi+h*60;

            if(!flag[num]&&res[0]=='A'&&res[1]=='C')
            {
                sum += time;
                flag[num] = 1;
                cnt++;
            }
            else if(!flag[num]) {
                sum += 20;
                c[num]++;
            }
            if(cnt == n)
                break;
        }
        for(int i = 1001; i <= 1013; i++) {
            if(!flag[i])
                sum -= (c[i]*20);
        }
        printf("%d %d\n",cnt,sum);

    }
    return 0;
}

 


Easy Summation

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


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(1T20), denoting the number of test cases.
Each of the following T lines contains two integers n(1n10000) and k(0k5).
 

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,k给出1到n的k次方和,k的大小最大只有5,XX说快速幂过的。。。。k最大就5不用快速乘法吧。。。。。每次相乘就取模,每次运算取一下摸,能取就取,避免出现高精度运算,暴力ll肯定能过。

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

typedef long long ll;
const ll mod=1000000000+7;

ll mypow(ll n,int k)
{
    ll ret=1;
    while(k--)
        ret=ret*n%mod;
    return ret;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,k;
        scanf("%d%d",&n,&k);
        ll ans=0;
        for(int i=1;i<=n;i++)
        {
            ans=(ans+mypow(i,k))%mod;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

Building Shops

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


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

The total cost consists of two parts. Building a candy shop at classroom i would have some cost ci. For every classroom P without any candy shop, then the distance between P and the rightmost classroom with a candy shop on P's left side would be included in the cost too. Obviously, if there is a classroom 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(1n3000), denoting the number of the classrooms.
In the following n lines, each line contains two integers xi,ci(109xi,ci109), denoting the coordinate of the i-th classroom and the cost of building a candy shop in it.
There are no two classrooms 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



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

这题题目有点难看懂;

题意: x轴上有n个班级,第i个班级建商店的费用为c[i];不建的话也会有费用,费用就是从i到距离i的左边最近的商店的距离,问总费用最少是多少;

题解:毫无疑问,第1个教室是肯定要建商店的;

然后就dp; dp[I][0]表示第I个教室不建商店,前I个教师的花费;

                    dp[I][1]表示第I个教室建商店,前I个教师的花费;

状态转移的话 dp[I][1] = min(dp[I-1][0],  dp[I-1][1]) + c[I]; 

                    dp[I][0] 的转移有点坑我一开始以为是由dp[I-1][0]转来的,然后贡献了一次wa;

                     是这样的,dp[I][0] = dp[j][0] + x[I]-x[j]; (j=1~I-1);

代码:

[cpp] view plain copy
 
  1. #include <iostream>  
  2. #include <cstdio>  
  3. #include <cstring>  
  4. #include <algorithm>  
  5. #include <cmath>  
  6. using namespace std;  
  7. typedef long long ll;  
  8. const int MAXN = 3008;  
  9. ll dp[MAXN][2];  
  10. //int path[MAXN];  
  11.   
  12. struct classroom {  
  13.     int x, c;  
  14. } ritian[MAXN];  
  15.   
  16. int cmp(classroom xx, classroom yy) {  
  17.     return xx.x < yy.x;  
  18. }  
  19.   
  20. int main() {  
  21.     int n;  
  22.     //freopen("in.txt", "r", stdin);  
  23.     while (~scanf("%d", &n)) {  
  24.         for(int i = 1; i <= n; i++)  
  25.             scanf("%d%d", &ritian[i].x, &ritian[i].c);  
  26.         sort(ritian+1, ritian+n+1, cmp);  
  27.         dp[1][0] = (ll)1<<60;  
  28.         dp[1][1] = ritian[1].c;  
  29.         for(int i = 2; i <= n; i++) {  
  30.             dp[i][1] = min(dp[i-1][0], dp[i-1][1])+ritian[i].c;  
  31.             ll tmp = 0;  
  32.             dp[i][0] = (ll)1<<60;  
  33.             for(int j = i-1; j > 0; j--) {  
  34.                 tmp = (ll)(ritian[j+1].x-ritian[j].x)*(i-j)+tmp;//这里少写了(ll)也贡献了2次wa,强迫症的我表示一个变量的值小于int型,我决不                       //会定义成long long 型->.->;  
  35.                 dp[i][0] = min(dp[i][0], dp[j][1]+tmp);  
  36.             }  
  37.         }  
  38.         printf("%I64d\n", min(dp[n][0], dp[n][1]));  
  39.     }  
  40.     return 0;  
  41. }  

题意: 小A要给他女朋友买一条n颗珠子的项链,他女朋友要求项链的珠子只有红和蓝这两种颜色,而且要保证每连续的奇数个珠子中,红珠子要大于等于蓝珠子;
2 <= n <= 10^18;问这条项链有多少个放珠子的方法;
题解: n > 4时, a[n] = a[n-1] + a[n-3],(需要时间推出来),意思是n相当于在n-1上加一个红珠子和在n-3上加一个红红蓝,这么说你懂我意思了吧, 然后上矩阵快速幂;
代码:
[cpp] view plain copy
 
  1. #include <iostream>  
  2. #include <cstdio>  
  3. #include <algorithm>  
  4. #include <cstring>  
  5. using namespace std;  
  6.   
  7. const int N=3;  
  8. typedef long long ll;  
  9. const ll Mod=1000000000+7;  
  10.   
  11. struct Mat  
  12. {  
  13.     ll mat[N+1][N+1];  
  14. };  
  15. Mat Multiply(Mat a, Mat b)  
  16. {  
  17.     Mat c;  
  18.     memset(c.mat, 0, sizeof(c.mat));  
  19.     for(int k = 0; k < N; ++k)  
  20.         for(int i = 0; i < N; ++i)  
  21.             if(a.mat[i][k])  
  22.                 for(int j = 0; j < N; ++j)  
  23.                     if(b.mat[k][j])  
  24.                         c.mat[i][j] = (c.mat[i][j] +a.mat[i][k] * b.mat[k][j])%Mod;  
  25.     return c;  
  26. }  
  27.   
  28. Mat QuickPower(Mat a, ll k)  
  29. {  
  30.     Mat c;  
  31.     memset(c.mat,0,sizeof(c.mat));  
  32.     for(int i = 0; i < N; ++i)  
  33.         c.mat[i][i]=1;  
  34.     for(; k; k >>= 1)  
  35.     {  
  36.         if(k&1) c = Multiply(c,a);  
  37.         a = Multiply(a,a);  
  38.     }  
  39.     return c;  
  40. }  
  41.   
  42. int main()  
  43. {  
  44.     int T;  
  45.     scanf("%d",&T);  
  46.     ll a[]={0,1,3,4,6};  
  47.     Mat A;  
  48.     A.mat[0][0]=1,A.mat[0][1]=1,A.mat[0][2]=0;  
  49.     A.mat[1][0]=0,A.mat[1][1]=0,A.mat[1][2]=1;  
  50.     A.mat[2][0]=1,A.mat[2][1]=0,A.mat[2][2]=0;  
  51.     while(T--)  
  52.     {  
  53.         ll n;  
  54.         scanf("%I64d",&n);  
  55.         if(n<=4)  
  56.         {  
  57.             printf("%I64d\n",a[n]);  
  58.             continue;  
  59.         }  
  60.         Mat ans=QuickPower(A,n-4);  
  61.         printf("%I64d\n",(a[4]*ans.mat[0][0]+a[3]*ans.mat[1][0]+a[2]*ans.mat[2][0])%Mod);  
  62.     }  
  63.     return 0;  
  64. }  
(上面两道来自老王)

Coprime Sequence

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


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(1T10), denoting the number of test cases.
In each test case, there is an integer n(3n100000) in the first line, denoting the number of integers in the sequence.
Then the following line consists of n integers a1,a2,...,an(1ai109), 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


大致题意:
前缀后缀gcd
       去掉一个元素能使这个数列的GCD最大为多少

分析:


       我们求一个数列的GCD,是先求前两个元素的GCD,然后将这个GCD值在与下一个元素进行GCD运算。由此可知进行GCD运算的顺序对最终的结果是没有影响的。我们再看看数列的长度范围,小于100000。那我们就枚举去掉的那个元素,那么去掉元素后的数列的GCD即这个元素前面一段数列的GCD再与这个元素后面一段数列的GCD进行GCD运算。所以我们需要两个数组分别记录前缀GCD和后缀GCD,这两个数组都可以通过O(n)算法算出来。


#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

int a[100000+5];
int pre[100000+5],suf[100000+5];

int gcd(int a, int b)
{
    while(b)
    {
        int c = a%b;
        a = b;
        b = c;
    }
    return a;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        for(int i=0; i<n; i++)
            scanf("%d",&a[i]);
        pre[0]=a[0];
        for(int i=1; i<n; i++)
        {
            pre[i]=gcd(pre[i-1],a[i]);
        }
        suf[n-1]=a[n-1];
        for(int i=n-2; i>=0; i--)
        {
            suf[i]=gcd(suf[i+1],a[i]);
        }
        int ans=max(suf[1],pre[n-2]);
        for(int i=1;i<n-1;i++)
        {
            ans=max(ans,gcd(pre[i-1],suf[i+1]));
        }
        printf("%d\n",ans);
    }
    return 0;
}

Graph Theory

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


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 i1).
(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(1T50), denoting the number of test cases.
In each test case, there is an integer n(2n100000) in the first line, denoting the number of vertices of the graph.
The following line contains n1 integers a2,a3,...,an(1ai2), 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

咋一看图论?,好吧,其实是找规律的题:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int MAXN = 100008;
int a[MAXN];


int main() {
    int n, T;
    //freopen("in.txt", "r", stdin);
    scanf("%d", &T);
    while (T--) {
        scanf("%d", &n);
        for(int i = 1; i < n; i++)
            scanf("%d", &a[i]);
        if (n%2) {
            printf("No\n");
            continue;
        }
        int p = 0;
        a[0] = 2;
        for(int i = n-1; i >= 0; i--) {
            if (a[i] == 1)
                p++;
            else p--;
            if (p < 0) break;
        }
        if (p < 0) printf("No\n");
        else printf("Yes\n");
    }
    return 0;
}



 

posted @ 2017-05-21 22:51  Lawliet__zmz  阅读(186)  评论(0编辑  收藏  举报