2016 icpc北京区域赛重现赛---题解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37868325/article/details/82940423

D - What a Beautiful Lake(水题)

题意:

 Weiming Lake, also named “Un-named Lake”, is the most famous scenic spot in Peking University. It is located in the north of the campus and is surrounded by walking paths, small gardens, and old red buildings with typical Chinese curly roofs. The lake was once the royal garden in Qing Dynasty. Boya tower stands on a little hill beside the lake. The lake and the tower form a distinctive landscape and a symbol of Peking University. Weiming Lake is a very good place for studying, reading, skating in the winter, and of course, jogging. More and more students and teachers run or walk around Weiming Lake every day and show how many paces they have covered in the mobile app WeChat Sports to get ”Zans” (applauses). ACMer X also enjoys jogging around Weiming Lake. His watch can measure and record an altitude value every meter. After a round of running, X collected the altitude data around the lake. Now he wants to find out the longest slope around the lake.

Input

There are no more than 20 test cases. Each case has two lines. The first line is an integer N (2 ≤ N ≤ 100) meaning that the length of the road around the lake is N meters. The second line contains N integers a1, a2 . . . aN , (0 ≤ a1, a2 . . . aN ≤ 100) indicating N altitude sample values around the lake. The samples are given in clockwise order, and the distance between two adjacent samples is one meter. Of course the distance between a1 and aN is also one meter. The input ends by a line of ‘0’.

Output

For each test case, print the length of the longest slope in meters. A slope is a part of the road around the lake, and it must keep going up or going down. If there are no slope, print ‘0’.

代码:

#include <bits/stdc++.h>
using namespace std;
const int MAXN=2*105;

int N,a[MAXN];

int main()
{
    a[0]=-1;
    while(scanf("%d",&N)!=EOF)
    {
        if(N==0) break;
        for(int i=1;i<=N;i++)
        {
            scanf("%d",&a[i]);
            a[i+N]=a[i];
        }
        bool flag=false;
        for(int i=2;i<=N;i++)
        {
            if(a[i]!=a[i-1]) flag=true;
        }
        if(flag==false)
        {
            printf("0\n");continue;
        }
        int uplen=0,downlen=0;
        int upans=0,downans=0;
        for(int i=2;i<=2*N;i++)
        {
            if(a[i]>a[i-1])
            {
                uplen++;
                upans=max(upans,uplen);
                downlen=0;
            }
            else if(a[i]<a[i-1])
            {
                downlen++;
                downans=max(downans,downlen);
                uplen=0;
            }
            else
            {
                uplen=0;downlen=0;
            }
        }
        printf("%d\n",max(upans,downans));
    }
    return 0;
}

E - What a Ridiculous Election(bfs+预处理)

 题意:

In country Light Tower, a presidential election is going on. There are two candidates, Mr. X1 and Mr. X2, and both of them are not like good persons. One is called a liar and the other is called a maniac. They tear(Chinese English word, means defame) each other on TV face to face, on newspaper, on internet . . . on all kinds of media. The country is tore into two parts because the people who support X1 are almost as many as the people who support X2. After the election day, X1 and X2 get almost the same number of votes. No one gets enough votes to win. According to the law of the country, the Great Judge must decide who will be the president. But the judge doesn’t want to offend half population of the country, so he randomly chooses a 6 years old kid Tom and authorize him to pick the president. Sounds weird? But the democracy in Light Tower is just like that. The poor or lucky little kid Tom doesn’t understand what is happening to his country. But he has his way to do his job. Tom’s ao shu(Chinese English word, means some kind of weird math for kids) teacher just left him a puzzle a few days ago, Tom decide that he who solve that puzzle in a better way will be president. The ao shu teacher’s puzzle is like this: Given a string which consists of five digits(‘0’..‘9’), like “02943”, you should change “12345” into it by as few as possible operations. There are 3 kinds of operations: 1. Swap two adjacent digits. 2. Increase a digit by one. If the result exceed 9, change it to it modulo 10. 3. Double a digit. If the result exceed 9, change it to it modulo 10. You can use operation 2 at most three times, and use operation 3 at most twice. As a melon eater (Chinese English again, means bystander), which candidate do you support? Please help him solve the puzzle.

Input

There are no more than 100,000 test cases. Each test case is a string which consists of 5 digits.

Output

For each case, print the minimum number of operations must be used to change “12345” into the given string. If there is no solution, print ‘-1’.

思路:

做的时候一直TLE。。主要是T太大了,,,

转换了很多种方法,最后已经完全转晕了,,,做不动了,,最后也没能A,,赛后看看,大佬们bfs+预处理好了就ok了,,

代码:


#include <iostream>

#include <stdio.h>

#include <algorithm>

#include <cmath>

#include <math.h>

#include <cstring>

#include <string>

#include <queue>

#include <stack>

#include <stdlib.h>

#include <list>

#include <map>

#include <set>

#include <bitset>

#include <vector>

#define mem(a,b) memset(a,b,sizeof(a))

#define findx(x) lower_bound(b+1,b+1+bn,x)-b

#define FIN      freopen("input.txt","r",stdin)

#define FOUT     freopen("output.txt", What a Ridiculous Election"w",stdout)

#define S1(n)    scanf("%d",&n)

#define SL1(n)   scanf("%I64d",&n)

#define S2(n,m)  scanf("%d%d",&n,&m)

#define SL2(n,m)  scanf("%I64d%I64d",&n,&m)

#define Pr(n)     printf("%d\n",n)

#define lson rt << 1, l, mid

#define rson rt << 1|1, mid + 1, r

 

using namespace std;

typedef long long ll;

const double PI=acos(-1);

const int INF=0x3f3f3f3f;

const double esp=1e-6;

const int maxn=1e5+5;

 

const int MOD=1000000007;

const int mod=1e9+7;

int dir[5][2]={0,1,0,-1,1,0,-1,0};

 

int ans[maxn][5][5];//次数

struct node{

    int num[10];

    int op2,op3;

    int step;

};

int Q_sum(node A)

{

    int sum=0;

    for(int i=1;i<=5;i++)

    {

        sum+=A.num[i];

        sum*=10;

    }

    return sum/10;

}

void bfs(node t)

{

    queue<node> Q;

    mem(ans,INF);

    t.op2=3;//  +1

    t.op3=2;//  *2

    t.step=0;

    Q.push(t);

    int n=Q_sum(t);

    ans[n][t.op2][t.op3]=0;

    while(!Q.empty())

    {

        node u=Q.front();

        Q.pop();

 

        for(int i=2;i<=5;i++)//swap

        {

            node tu=u;

            swap(tu.num[i],tu.num[i-1]);

            int  num=Q_sum(tu);

            tu.step++;

            if(tu.step>=ans[num][tu.op2][tu.op3])

                continue;

            Q.push(tu);

            ans[num][tu.op2][tu.op3]=tu.step;

        }

        if(u.op2>0)//+1

        {

            for(int i=1;i<=5;i++)

            {

                node tu=u;

                tu.op2--;

                tu.num[i]=(tu.num[i]+1)%10;

                int num=Q_sum(tu);

                tu.step++;

                if(tu.step>=ans[num][tu.op2][tu.op3])

                    continue;

                Q.push(tu);

                ans[num][tu.op2][tu.op3]=tu.step;

            }

        }

        if(u.op3>0)//*2

        {

            for(int i=1;i<=5;i++)

            {

                node tu=u;

                tu.op3--;

                tu.num[i]=(tu.num[i]*2)%10;

                int num=Q_sum(tu);

                tu.step++;

                if(tu.step>=ans[num][tu.op2][tu.op3])

                    continue;

                Q.push(tu);

                ans[num][tu.op2][tu.op3]=tu.step;

            }

        }

    }

}

int main()

{

    node temp;

    for(int i=1;i<=5;i++)

        temp.num[i]=i;

    bfs(temp);

    char str[12];

    while(~scanf("%s",str+1))

    {

        node b;

        for(int i=1;i<=5;i++)

            b.num[i]=str[i]-'0';

        int n=Q_sum(b);

        int res=INF;

        for(int i=0;i<=3;i++)

            for(int j=0;j<=2;j++)

        {

            res=min(res,ans[n][i][j]);

        }

 

        if(res==INF)

            printf("-1\n");

        else

            printf("%d\n",res);

    }

    return 0;

}

F - What a Simple Research(排序水题)

 题意:

Peking University Student Folk Music Band has a history of more than 90 years. They play Chinese traditional music by Chinese traditional instruments, such as Pipa, Erhu and Guzheng, etc. Doctor Li is a member of that band, and also a former ACMer. Now he is doing some research on Chinese ancient music. Many Chinese ancient music has only five kinds of tones, which can be denoted by ‘C’,‘D’,‘E’,‘G’, and ‘A’. Given a piece of music score, Li wants to do some simple statistics.

Input

There are no more than 20 test cases. In each test case: The first line contains two integers n and m (2 ≤ n, m ≤ 20), indicating that a piece of music score is represented by an n × m matrix of tones. Only ‘C’,‘D’,‘E’,‘G’, and ‘A’ can appear in the matrix. Then the n × m matrix follows. The input ends with a line of ‘0 0’.

Output

For each test case: For each kind of tone shown in the matrix, calculate the appearing times of it, and print the result in descending order according to the appearing times. If more than one kind of tones has the same appearing times, print them in the lexicographical order.

思路:就是n*m的字符矩阵中,每个字符的数量,数量为0的不输出,其他的按题目要求排个序就可以

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m;
struct AA
{
    char ch;
    int num;
    bool operator<(const AA&aa)const
    {
        if(num==aa.num) return ch<aa.ch;
        return num>aa.num;
    }
}pos[30];
int T;
int main()
{
    char ch[30];
    while(~scanf("%d%d",&n,&m))
    {
        if(n==0&&m==0) break;
        for(int i=0;i<26;i++)
        {
            pos[i].ch='A'+i;
            pos[i].num=0;
        }

        for(int i=1;i<=n;i++)
        {
            scanf("%s",ch);

            for(int j=0;j<m;j++)
            {
                pos[ch[j]-'A'].num++;
            }
        }
        sort(pos,pos+26);
        for(int i=0;i<=25;i++)
        {
            if(pos[i].num==0) break;
            if(pos[i+1].num!=0)
            cout<<pos[i].ch<<" "<<pos[i].num<<" ";
            else
            {
                cout<<pos[i].ch<<" "<<pos[i].num<<endl;
            }
        }
    }


}

K - JiLi Number(打表暴力查找)

题意:

Driver Ji likes the digit “1”. He has an accumulator which shows the sum of input number. He lists all of positive number no more than N and starts counting from one, two, three . . . Every time he counts a number he will add the number of digit “1” in this number to accumulator at the same time. The amazing thing happens! At some times, when he finishes counting a number X, the number which on the accumulator is X exactly, he will regard X as “JiLi Number” which means lucky number. Now he wants to know the number of “JiLi Numbers” and the biggest “JiLi Number” no more than N.

Input

There are several test cases and the each test case is a line contains an positive integer N, (1 < N ≤ 10100)

Output

For each test case, output two integers which donates the number of “JiLi Numbers” and the biggest “JiLi Number”.

思路:

暴力打个表,83以后就不输出了,猜了一下一共83个,真是良心样例!

代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

ll num[83]={1,199981,199982,199983,199984,199985,199986,199987,199988,199989,199990,200000,200001,1599981,1599982,1599983,1599984,1599985,1599986,1599987,1599988,1599989,1599990,2600000,2600001,13199998,35000000,35000001,35199981,35199982,35199983,35199984,35199985,35199986,35199987,35199988,35199989,35199990,35200000,35200001,117463825,500000000,500000001,500199981,500199982,500199983,500199984,500199985,500199986,500199987,500199988,500199989,500199990,500200000,500200001,501599981,501599982,501599983,501599984,501599985,501599986,501599987,501599988,501599989,501599990,502600000,502600001,513199998,535000000,535000001,535199981,535199982,535199983,535199984,535199985,535199986,535199987,535199988,535199989,535199990,535200000,535200001,1111111110};
string s;

int main()
{
    num[83]=100000000000;
    while(cin>>s)
    {
        if(s.length()>11)
            cout<<83<<" "<<1111111110<<endl;
        ll n=0;
        //for(int i=s.length()-1;i>=0;i--)
            //n+=s[i]*pow(10,i);
        for(int i=0;i<=s.length()-1;i++)
        {
            n=n*10+s[i]-'0';
        }
        //cout<<n<<endl;
        for(int i=0;i<=82;i++)
        {
            if(n>=num[i]&&num[i+1]>n)
            {
                cout<<(i+1)<<" "<<num[i]<<endl;
                break;
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37868325/article/details/82940423
今日推荐