codeforces Educational Codeforces Round 41 (2018.4.4)

A. Tetris
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given a following process.

There is a platform with n n columns. 1×1 squares are appearing one after another in some columns on this platform. If there are no squares in the column, a square will occupy the bottom row. Otherwise a square will appear at the top of the highest square of this column.

When all of the n n columns have at least one square in them, the bottom row is being removed. You will receive 1 point for this, and all the squares left will fall down one row.

You task is to calculate the amount of points you will receive.

Input
The first line of input contain 2 integer numbers n n and m ( 1n,m1000 1 ≤ n , m ≤ 1000 ) — the length of the platform and the number of the squares.

The next line contain m m integer numbers c1,c2,,cm ( 1cin 1 ≤ c i ≤ n ) — column in which i i -th square will appear.

Output
Print one integer — the amount of points you will receive.

Example
inputCopy
3 9
1 1 2 2 2 3 1 2 3
output
2
Note
In the sample case the answer will be equal to 2 because after the appearing of 6 6 -th square will be removed one row (counts of the squares on the platform will look like [2 3 1], and after removing one row will be [1 2 0] [ 1   2   0 ] ).

After the appearing of 9 9 -th square counts will be [2 3 1], and after removing one row it will look like [1 2 0] [ 1   2   0 ] .

So the answer will be equal to 2 2 <script type="math/tex" id="MathJax-Element-1257">2</script>.

暴力模拟一下

#include<cstdio>
int a[1001];
int hash[1001];
int cnt;
int pt;
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        int tmp;
        scanf("%d",&tmp);
        a[tmp]++;
        if(!hash[tmp])
        {hash[tmp]=1;
        cnt++;}
        if(cnt==n)
        {
            pt++;
            cnt=0;
            for(int i=1;i<=n;i++)
            {
                if(a[i])a[i]--;
                if(!a[i])
                {hash[i]=0;
                }
                else cnt++;
            }
        }
    }
    printf("%d\n",pt);
    return 0;
}

B. Lecture Sleep
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Your friend Mishka and you attend a calculus lecture. Lecture lasts n minutes. Lecturer tells ai theorems during the i-th minute.

Mishka is really interested in calculus, though it is so hard to stay awake for all the time of lecture. You are given an array t of Mishka’s behavior. If Mishka is asleep during the i-th minute of the lecture then ti will be equal to 0, otherwise it will be equal to 1. When Mishka is awake he writes down all the theorems he is being told — ai during the i-th minute. Otherwise he writes nothing.

You know some secret technique to keep Mishka awake for k minutes straight. However you can use it only once. You can start using it at the beginning of any minute between 1 and n - k + 1. If you use it on some minute i then Mishka will be awake during minutes j such that and will write down all the theorems lecturer tells.

You task is to calculate the maximum number of theorems Mishka will be able to write down if you use your technique only once to wake him up.

Input
The first line of the input contains two integer numbers n and k (1 ≤ k ≤ n ≤ 105) — the duration of the lecture in minutes and the number of minutes you can keep Mishka awake.

The second line of the input contains n integer numbers a1, a2, … an (1 ≤ ai ≤ 104) — the number of theorems lecturer tells during the i-th minute.

The third line of the input contains n integer numbers t1, t2, … tn (0 ≤ ti ≤ 1) — type of Mishka’s behavior at the i-th minute of the lecture.

Output
Print only one integer — the maximum number of theorems Mishka will be able to write down if you use your technique only once to wake him up.

Example
inputCopy
6 3
1 3 5 2 5 4
1 1 0 1 0 0
output
16
Note
In the sample case the better way is to use the secret technique at the beginning of the third minute. Then the number of theorems Mishka will be able to write down will be equal to 16.
注意如果遍历起点会T(T了好多次),因为k可能和n同样数量级,遍历终点,一边读数据一边写当前时间作为终点时的收益。

#include<cstdio>
#include<algorithm>
using namespace std;
int be[100005];
int th[100005];
int ti;
int cnt;
int sl[100005];
int im;
//int imp[100005];//当前截止时,获得的改善 
int tpp;//当前改善 
int tpm;//当前最大值 
int main()
{
    int d,k,s1=0,s2=0;
    scanf("%d%d",&d,&k);
    for(int i=0;i<d;i++)
    {
        scanf("%d",&th[i]);
    }
    for(int i=0;i<d;i++)
    {
        scanf("%d",&be[i]);
        if(be[i]==1)ti+=th[i];
        if(i<k-1)
        {
            if(!be[i])
            tpp+=th[i];
            //printf("i: %d improve %d\n",i,tpp);
        }
        else
        {
            tpp=tpp+th[i]*(be[i]==0)-th[i-k]*(be[i-k]==0);
            tpm=max(tpm,tpp);
            //printf("i: %d improve %d\n",i,tpp);
        }
        //else {
        //sl[cnt++]=i;
        //}
    }
    //printf("%d\n",ti);
/*  for(int i=0;i<cnt;i++)
    {
        int st=sl[i];
        //printf("%d\n",st);
        if(st>d-k)st=d-k;
        int tp=0;
        for(int i=0;i<k;i++)
        {
            if(!be[st+i])tp+=th[st+i];
        }
        //if(!be[st+1])tp+=th[st+1];
        //if(!be[st+2])tp+=th[st+2];
        if(im<tp)im=tp;
    }*/
    printf("%d\n",tpm+ti);
    return 0;
}

C. Chessboard
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Magnus decided to play a classic chess game. Though what he saw in his locker shocked him! His favourite chessboard got broken into 4 pieces, each of size n by n, n is always odd. And what’s even worse, some squares were of wrong color. j-th square of the i-th row of k-th piece of the board has color ak, i, j; 1 being black and 0 being white.

Now Magnus wants to change color of some squares in such a way that he recolors minimum number of squares and obtained pieces form a valid chessboard. Every square has its color different to each of the neightbouring by side squares in a valid board. Its size should be 2n by 2n. You are allowed to move pieces but not allowed to rotate or flip them.

Input
The first line contains odd integer n (1 ≤ n ≤ 100) — the size of all pieces of the board.

Then 4 segments follow, each describes one piece of the board. Each consists of n lines of n characters; j-th one of i-th line is equal to 1 if the square is black initially and 0 otherwise. Segments are separated by an empty line.

Output
Print one number — minimum number of squares Magnus should recolor to be able to obtain a valid chessboard.

Examples
inputCopy
1
0

0

1

0
output
1
inputCopy
3
101
010
101

101
000
101

010
101
011

010
101
010
output
2
棋盘块只有两种,中间是0和中间是1,各有两块,数据不大暴力判断一下就行。(注意是行差+列差的奇偶性体现是否与中间相同)。

#include<cstdio>
#include<algorithm>
using namespace std;
char a[4][100][100];
int c[6];
int check(int le,int s,char st)//le:ceng,   s:大小, st:中间值 ,   s/2+1
{
    int ct=0;
    for(int i=0;i<s;i++)
    {
        for(int j=0;j<s;j++)
        {
            //printf("check a %d %d %d,(i-(s-1)/2+j-(s-1)/2)%2:%d \n",le,i,j,(i-(s-1)/2+j-(s-1)/2)%2);
            if((i-(s-1)/2+j-(s-1)/2)%2==0&&a[le][i][j]!=st)
            {
                ct++;
            //  printf("a %d %d %d is %c should modify\n",le,i,j,a[le][i][j]);
            }
            else if((i-(s-1)/2+j-(s-1)/2)%2!=0&&a[le][i][j]==st)
            {
                ct++;
                //printf("a %d %d %d is %c should modify\n",le,i,j,a[le][i][j]);
            }
        }
    }
    //printf("check %d as standard %c it should modify %d\n",le,st,ct);
    return ct;
}
int main()
{
    int si;
    scanf("%d",&si);
    getchar();
    for(int k=0;k<4;k++)
    {
        for(int i=0;i<si;i++)
        {
            char s[101];
            scanf("%s",&s);
            for(int r=0;r<si;r++)
                a[k][i][r]=s[r];
            getchar();
        }
        if(k!=3)getchar();
    }
    /*for(int k=0;k<4;k++)
    {
        for(int i=0;i<si;i++)
        {
            for(int j=0;j<si;j++)
            printf("%c",a[k][i][j]);
            printf("\n");
        }
        printf("\n");
    }*/
    c[0]=check(0,si,'1')+check(1,si,'1')+check(2,si,'0')+check(3,si,'0');
    c[1]=check(0,si,'1')+check(1,si,'0')+check(2,si,'1')+check(3,si,'0');
    c[2]=check(0,si,'1')+check(1,si,'0')+check(2,si,'0')+check(3,si,'1');
    c[3]=check(0,si,'0')+check(1,si,'1')+check(2,si,'1')+check(3,si,'0');
    c[4]=check(0,si,'0')+check(1,si,'1')+check(2,si,'0')+check(3,si,'1');
    c[5]=check(0,si,'0')+check(1,si,'0')+check(2,si,'1')+check(3,si,'1');
    int ans=40000;
    for(int i=0;i<6;i++)
    {
        ans=min(c[i],ans);
    }
    printf("%d\n",ans);
    return 0;
}

D. Pair Of Lines
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given n points on Cartesian plane. Every point is a lattice point (i. e. both of its coordinates are integers), and all points are distinct.

You may draw two straight lines (not necessarily distinct). Is it possible to do this in such a way that every point lies on at least one of these lines?

Input
The first line contains one integer n (1 ≤ n ≤ 105) — the number of points you are given.

Then n lines follow, each line containing two integers xi and yi (|xi|, |yi| ≤ 109)— coordinates of i-th point. All n points are distinct.

Output
If it is possible to draw two straight lines in such a way that each of given points belongs to at least one of these lines, print YES. Otherwise, print NO.

Examples
inputCopy
5
0 0
0 1
1 1
1 -1
2 2
output
YES
inputCopy
5
0 0
1 0
2 1
1 1
2 3
output
NO
Note
In the first example it is possible to draw two lines, the one containing the points 1, 3 and 5, and another one containing two remaining points.
思路是:(4以下一定yes),起始三个点一定有两个点确定一条最终直线,判断这条直线是否满足条件,把0、1、2都判断一下。判断函数写错了(计算几何还不熟),没能A,借鉴的其他博主的代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
ll x[N],y[N];
int n;
bool gx(int a,int b,int c,int d)
{
    return (x[b]-x[a])*(y[d]-y[c])==(x[d]-x[c])*(y[b]-y[a]);
}
int check(int d,int f)
{
    vector<int>V;
    for(int i=1; i<=n; i++)
        if(!gx(d,f,f,i))V.push_back(i);
    if(V.size()<3)return 1;
    for(int i=2; i<(int)V.size(); i++)
        if(!gx(V[0],V[1],V[1],V[i]))return 0;
    return 1;
}
int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
        cin>>x[i]>>y[i];
    if(n<5||check(1,2)||check(2,3)||check(1,3))
        cout<<"YES";
    else cout<<"NO";
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_viceversa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值