Codeforces Round #Pi (Div. 2) A~D 题解B C D

来源:互联网 发布:linux who命令 编辑:程序博客网 时间:2024/05/16 15:27

A. Lineland Mail

Problem Description:
All cities of Lineland are located on the Ox coordinate axis. Thus, each city is associated with its position xi — a coordinate on the Ox axis. No two cities are located at a single point.

Lineland residents love to send letters to each other. A person may send a letter only if the recipient lives in another city (because if they live in the same city, then it is easier to drop in).

Strange but true, the cost of sending the letter is exactly equal to the distance between the sender’s city and the recipient’s city.

For each city calculate two values ​​mini and maxi, where mini is the minimum cost of sending a letter from the i-th city to some other city, and maxi is the the maximum cost of sending a letter from the i-th city to some other city

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<math.h>#include<queue>#include<stack>#include<vector>#include<map>#include<set>using namespace std;#define rfor(i,a,b) for(i=a;i<=b;i++)#define lfor(i,a,b) for(i=a;i>=b;i--)#define mem(a,b) memset(a,b,sizeof(a))struct node{    int x,num;};node s[100005];int ans[100005][2];int cmp(node u,node v){    return u.x<v.x;}int main(){    int i,n;    while(~scanf("%d",&n))    {        rfor(i,1,n)        {            scanf("%d",&s[i].x);            s[i].num=i;        }        sort(s+1,s+n+1,cmp);        rfor(i,1,n)        {            int x=s[i].x,num=s[i].num;            if(i==1)            {                ans[num][0]=abs(x-s[i+1].x);                ans[num][1]=s[n].x-x;            }            else if(i==n)            {                ans[num][0]=abs(x-s[i-1].x);                ans[num][1]=abs(x-s[1].x);            }            else            {                ans[num][0]=min(abs(x-s[i+1].x),abs(x-s[i-1].x));                ans[num][1]=max(abs(x-s[1].x),s[n].x-x);            }        }        rfor(i,1,n)        printf("%d %d\n",ans[i][0],ans[i][1]);    }    return 0;}

B. Berland National Library
Problem Description:

Berland National Library has recently been built in the capital of Berland. In addition, in the library you can take any of the collected works of Berland leaders, the library has a reading room.

Today was the pilot launch of an automated reading room visitors’ accounting system! The scanner of the system is installed at the entrance to the reading room. It records the events of the form “reader entered room”, “reader left room”. Every reader is assigned a registration number during the registration procedure at the library — it’s a unique integer from 1 to 106. Thus, the system logs events of two forms:

“+ ri” — the reader with registration number ri entered the room;
“- ri” — the reader with registration number ri left the room.
The first launch of the system was a success, it functioned for some period of time, and, at the time of its launch and at the time of its shutdown, the reading room may already have visitors.

Significant funds of the budget of Berland have been spent on the design and installation of the system. Therefore, some of the citizens of the capital now demand to explain the need for this system and the benefits that its implementation will bring. Now, the developers of the system need to urgently come up with reasons for its existence.

Help the system developers to find the minimum possible capacity of the reading room (in visitors) using the log of the system available to you.

题意:
图书馆阅读室门口有个能记录有人进出的机器.
给你一段记录,可能开始记录的时候里边还有人
问你这个阅读室最少能容纳多少人
思路:
把没记录进去但记录过出去的人加在最开始就行了

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<math.h>#include<queue>#include<stack>#include<string>#include<vector>#include<map>#include<set>using namespace std;#define lowbit(x) (x&(-x))typedef long long LL;const int maxn = 1000005;const int inf=(1<<28)-1;int mark[maxn];pair<int,int>Par[505];char str[5];int main(){    int n;    scanf("%d",&n);    for(int i=1;i<=n;++i)    {        int Num;        scanf("%s%d",str,&Par[i].first);        Par[i].second=str[0]=='+'? 1 : -1;    }    int tmp=0;    for(int i=1;i<=n;++i)    if(Par[i].second==1)    {        mark[Par[i].first]=1;    }    else    {        if(mark[Par[i].first]==0) tmp++;        else mark[Par[i].first]=0;    }    memset(mark,0,sizeof(mark));    int ans=tmp;    for(int i=1;i<=n;++i)    if(Par[i].second==1)    {        mark[Par[i].first]=1;        tmp++;        ans=max(tmp,ans);    }    else    {        tmp--;        if(mark[Par[i].first])         {            mark[Par[i].first]=0;        }        ans=max(ans,tmp);    }    printf("%d\n",ans);    return 0;}

C. Geometric Progression
Problem Description:

Polycarp loves geometric progressions very much. Since he was only three years old, he loves only the progressions of length three. He also has a favorite integer k and a sequence a, consisting of n integers.

He wants to know how many subsequences of length three can be selected from a, so that they form a geometric progression with common ratio k.

A subsequence of length three is a combination of three such indexes i1, i2, i3, that 1 ≤ i1 < i2 < i3 ≤ n. That is, a subsequence of length three are such groups of three elements that are not necessarily consecutive in the sequence, but their indexes are strictly increasing.

A geometric progression with common ratio k is a sequence of numbers of the form b·k0, b·k1, …, b·kr - 1.

Polycarp is only three years old, so he can not calculate this number himself. Help him to do it.

题意:
给你一段长度为n的序列,让你从中选三个递增的数
这三个数必须满足b*k^t,b*k^(t+1),b*k^(t+2)
问能选出多少组这样的数
思路:
特判一下k==1的情况和x==0的情况
然后就行dp
dp[i][j][k]代表b==i,t==j并且是这三个数的第k个数有多少种情况
dp[i][j][1]++
dp[i][j][2]+=dp[i][j-1][1]
ans+=dp[i][j-1][2]就能得到答案了

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<math.h>#include<queue>#include<stack>#include<string>#include<vector>#include<map>#include<set>using namespace std;#define lowbit(x) (x&(-x))typedef long long LL;const int maxn = 200005;const int inf=(1<<28)-1;vector<pair<int,int> >vec;LL dp[maxn][35][4];map<int,int>Map;int tot=0;int main(){    int n,k;    scanf("%d%d",&n,&k);    if(k==1)    {        int Num=0;        for(int i=1;i<=n;++i)        {            int x;            scanf("%d",&x);            if(!Map[x]) Map[x]=++tot;            vec.push_back(make_pair(Map[x],1));        }        LL ans=0;        for(int i=0;i<n;++i)        {            int x=vec[i].first;            ans+=dp[x][2][1];            dp[x][2][1]+=dp[x][1][1];            dp[x][1][1]++;        }        printf("%lld\n",ans);        return 0;    }    int Num=0;    for(int i=1;i<=n;++i)    {        int x;        scanf("%d",&x);        if(x==0)         {            Num++;            continue;        }        //if(x%k&&x>=k) continue;        int pow_num=0,tmp=x;        while(tmp%k==0)        {            tmp/=k;pow_num++;        }        if(Map[tmp]==0) Map[tmp]=++tot;        //printf("%d ",x);        //printf("%d %d\n",tmp,pow_num);        vec.push_back(make_pair(tmp,pow_num));    }    memset(dp,0,sizeof(dp));    LL ans=0;    int Size=vec.size();    for(int i=0;i<Size;++i)    {        pair<int,int>Par;        Par=vec[i];        dp[Map[Par.first]][Par.second][1]++;        //for(int j=0;j<Par.second;++j)        //{            dp[Map[Par.first]][Par.second][2]+=dp[Map[Par.first]][Par.second-1][1];            ans+=dp[Map[Par.first]][Par.second-1][2];        //}        //printf("%d: %lld\n",i,ans);    }    LL Cnt1=0,Cnt2=0;    for(int i=1;i<=Num;++i)    {        ans+=Cnt2;        Cnt2+=Cnt1;        Cnt1++;    }    printf("%lld\n",ans);    return 0;}

D. One-Dimensional Battle Ships
Problem Description:

Alice and Bob love playing one-dimensional battle ships. They play on the field in the form of a line consisting of n square cells (that is, on a 1 × n table).

At the beginning of the game Alice puts k ships on the field without telling their positions to Bob. Each ship looks as a 1 × a rectangle (that is, it occupies a sequence of a consecutive squares of the field). The ships cannot intersect and even touch each other.

After that Bob makes a sequence of “shots”. He names cells of the field and Alice either says that the cell is empty (“miss”), or that the cell belongs to some ship (“hit”).

But here’s the problem! Alice like to cheat. May be that is why she responds to each Bob’s move with a “miss”.

Help Bob catch Alice cheating — find Bob’s first move, such that after it you can be sure that Alice cheated.

题意:
给你一个长度为n的一维的图形,往上边放长度为a的船,放k个
船与船之间不能重叠和相邻
然后按顺序给出不能占用的点,问在给出第几个点的时候就不能放k个船了
思路:
不能相邻的话,我们就把每个船的长度都加长一格,然后因为总会有个在边上
所以我们把区间长度+1,所以能放(len+1)/(a+1)个船
然后用Set统计每次插入要损失几个船就行了

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<math.h>#include<queue>#include<stack>#include<string>#include<vector>#include<map>#include<set>using namespace std;#define lowbit(x) (x&(-x))typedef long long LL;const int maxn = 200005;const int inf=(1<<28)-1;set<int>Set;set<int>::iterator it;int main(){    int n,k,a,m;    scanf("%d%d%d",&n,&k,&a);    scanf("%d",&m);    Set.insert(0);Set.insert(n+1);    int ans=-1,now=(n+1)/(a+1);    if(now<k) ans=1;    for(int i=1;i<=m;++i)    {        int x;        scanf("%d",&x);        if(ans!=-1) continue;        it=Set.upper_bound(x);        int Right=*it;        --it;        int Left=*it;        int t=(Right-Left)/(a+1);        int tmp=(Right-x)/(a+1)+(x-Left)/(a+1);        now-=t-tmp;        if(now<k) ans=i;        Set.insert(x);        //printf("**%d %d %d %d %d\n",now,Left,Right,t,tmp);    }    printf("%d\n",ans);    return 0;}
0 0
原创粉丝点击