Codeforces Round #521 (Div. 3)

昨天跟pyl和zh在vj上拉了一份题 结果被两个大佬吊打(哭唧唧( ; ´ ༎ຶ  Д ༎ຶ ` ),记录一下前四个题来记录一下被吊打的心情

传送门http://codeforces.com/contest/1077

A. Frog Jumping

我在这http://codeforces.com/contest/1077/problem/A

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

A frog is currently at the point 00 on a coordinate axis OxOx. It jumps by the following algorithm: the first jump is aa units to the right, the second jump is bb units to the left, the third jump is aa units to the right, the fourth jump is bb units to the left, and so on.

Formally:

  • if the frog has jumped an even number of times (before the current jump), it jumps from its current position xx to position x+ax+a;
  • otherwise it jumps from its current position xx to position x−bx−b.

Your task is to calculate the position of the frog after kk jumps.

But... One more thing. You are watching tt different frogs so you have to answer tt independent queries.

Input

The first line of the input contains one integer tt (1≤t≤10001≤t≤1000) — the number of queries.

Each of the next tt lines contain queries (one query per line).

The query is described as three space-separated integers a,b,ka,b,k (1≤a,b,k≤1091≤a,b,k≤109) — the lengths of two types of jumps and the number of jumps, respectively.

Output

Print tt integers. The ii-th integer should be the answer for the ii-th query.

题意就是一只呱呱 奇数次往右跳 偶数次往左跳 一共跳K次,问最后跳到哪里

默默的说一句 英语好啊!yl巨巨两分钟就A惹,而我读题两分钟都不止ヽ(*。>Д< )o゜,

分一下总步数是奇数还是偶数 因为是以第一步开始的(这不废话嘛,所以如果跳的是奇数步的话,那就会多往右跳一次,如果是偶数步的话,往左和往右跳的次数是相同的)往右跳总的距离-往左跳总的距离 

由于是第一步是往右的,所以就右就是正方向。由于数据范围是10^9 一不小心就越界了(对,我踩了坑!),所以,我们可以

把往左和往右的总距离提一个公因子,先做减法 然后再乘 就不会越界惹...

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int T;
	long long a, b, k, m;
	scanf("%d", &T);
	while(T--)
	{
		cin>>a>>b>>k;
		if (!(k&1))
		{
			m = ((a - b)*k) / 2;//a*k/2-b*k/2 提公子因
        }
		else
		{
			m = ((a - b)*(k - 1)) / 2 + a; //a*((k-1)/2)+a-b*((k-1)/2)
		}
		cout<<m<<endl;
	}
	return 0;
}

B Disturbed People

我在这http://codeforces.com/contest/1077/problem/B

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

There is a house with nn flats situated on the main street of Berlatov. Vova is watching this house every night. The house can be represented as an array of nn integer numbers a1,a2,…,ana1,a2,…,an, where ai=1ai=1 if in the ii-th flat the light is on and ai=0ai=0 otherwise.

Vova thinks that people in the ii-th flats are disturbed and cannot sleep if and only if 1<i<n1<i<n and ai−1=ai+1=1ai−1=ai+1=1 and ai=0ai=0.

Vova is concerned by the following question: what is the minimum number kk such that if people from exactly kk pairwise distinct flats will turn off the lights then nobody will be disturbed? Your task is to find this number kk.

Input

The first line of the input contains one integer nn (3≤n≤1003≤n≤100) — the number of flats in the house.

The second line of the input contains nn integers a1,a2,…,ana1,a2,…,an (ai∈{0,1}ai∈{0,1}), where aiai is the state of light in the ii-th flat.

Output

Print only one integer — the minimum number kk such that if people from exactly kk pairwise distinct flats will turn off the light then nobody will be disturbed.

大体意思就是 只有     ai−1==1&&ai==1ai&&ai==0才算是被打扰了,求被打扰变成不被打扰的 关的最少的灯k

从第一个开始 从左往右,要想关灯数最少 那可以关最被打扰的人的右边的灯,这其实是一种贪心思想。因为关右边的话,可能会帮助下一个被打扰的人关了灯,如果关左边的话,可能就只有帮自己关灯只一个作用(因为从左往右 左边已经做好操作了)

所以我们就看是不是符合打扰的条件,如果符合就关灯 更新状态 再看下一个窗口

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1000005;
int n;
int a[maxn];
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    int k=0;
    for(int i=2;i<n;i++)
    {
        if(a[i]==0&&a[i-1]==1&&a[i+1]==1)
        {
            k++;
            a[i+1]=0;//关灯 更新状态
        }
    }
    printf("%d\n",k);
}

C. Good Array

我在这http://codeforces.com/contest/1077/problem/C

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

Let's call an array good if there is an element in the array that equals to the sum of all other elements. For example, the array a=[1,3,3,7]a=[1,3,3,7] is good because there is the element a4=7a4=7 which equals to the sum 1+3+31+3+3.

You are given an array aa consisting of nn integers. Your task is to print all indices jj of this array such that after removing the jj-th element from the array it will be good (let's call such indices nice).

For example, if a=[8,3,5,2]a=[8,3,5,2], the nice indices are 11 and 44:

  • if you remove a1a1, the array will look like [3,5,2][3,5,2] and it is good;
  • if you remove a4a4, the array will look like [8,3,5][8,3,5] and it is good.

You have to consider all removals independently, i. e. remove the element, check if the resulting array is good, and return the element into the array.

Input

The first line of the input contains one integer nn (2≤n≤2⋅1052≤n≤2⋅105) — the number of elements in the array aa.

The second line of the input contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1061≤ai≤106) — elements of the array aa.

Output

In the first line print one integer kk — the number of indices jj of the array aa such that after removing the jj-th element from the array it will be good (i.e. print the number of the nice indices).

In the second line print kk distinct integers j1,j2,…,jkj1,j2,…,jk in any order — nice indices of the array aa.

If there are no such indices in the array aa, just print 00 in the first line and leave the second line empty or do not print it at all.

我这个英语渣渣刚开始又理解错题意惹,对了对了,顺便说一句,一周后我四级一定会过!!!!

好的数组是 有一个数等于数组中其他所有数的和,如果不符合的话,就要删除不符合的数的下标

既然有一个数等于数组中其他所有数的和,那么这个数肯是这个数组中比较大的数才会是其他数的和,这里为什么说是比较大的数呢?因为有不符合的情况让你删除鸭。 

我们可以记一下除最大的数外所有数的和S,然后用这个和S-任意一个ai看是不是等于最大的数,如果相等的话,那就找到了一个。如果都不相等的话,由于一次只能删一个(但可以删多次不同的),所以肯定第二大的数等于其他数之和,而最大的数是多余的那个,就删除最大的数。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int const maxn=200005;
int no[maxn];
//由于要输出下标所以用结构体的num记录下标
//再按val从小到大排序
struct node
{
    int val;
    int num;

    bool operator < (const node &t) const
    {
        return val<t.val;
    }
}a[maxn];

int main()
{
    int n;
    cin>>n;
    ll sum=0;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i].val;
        a[i].num=i;
        sum+=a[i].val;
    }
    sort(a+1,a+n+1);
    sum=sum-a[n].val;//除最大的数其他数的和
//    for(int i=1;i<=n;i++)
//        cout<<a[i].val<<' ';
    int cnt=0;
    for(int i=1;i<n;i++)
    {
        if((sum-a[i].val)==a[n].val)//如果减去多余的等于sum
        {
            no[cnt++]=a[i].num;
        }
    }
    if(sum-a[n-1].val==a[n-1].val)//如果多余的是最大的数
    {
        no[cnt++]=a[n].num;
    }
    cout<<cnt<<endl;
    for(int i=0;i<cnt;i++)
    {
        cout<<no[i]<<' ';
    }
}

D. Cutting Out

我在这http://codeforces.com/contest/1077/problem/D

time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given an array ss consisting of nn integers.

You have to find any array tt of length kk such that you can cut out maximum number of copies of array tt from array ss.

Cutting out the copy of tt means that for each element titi of array tt you have to find titi in ss and remove it from ss. If for some titi you cannot find such element in ss, then you cannot cut out one more copy of tt. The both arrays can contain duplicate elements.

For example, if s=[1,2,3,2,4,3,1]s=[1,2,3,2,4,3,1] and k=3k=3 then one of the possible answers is t=[1,2,3]t=[1,2,3]. This array tt can be cut out 22 times.

  • To cut out the first copy of tt you can use the elements [1,2––,3,2,4,3––,1––][1,2_,3,2,4,3_,1_] (use the highlighted elements). After cutting out the first copy of tt the array ss can look like [1,3,2,4][1,3,2,4].
  • To cut out the second copy of tt you can use the elements [1––,3––,2––,4][1_,3_,2_,4]. After cutting out the second copy of tt the array ss will be [4][4].

Your task is to find such array tt that you can cut out the copy of tt from ss maximum number of times. If there are multiple answers, you may choose any of them.

Input

The first line of the input contains two integers nn and kk (1≤k≤n≤2⋅1051≤k≤n≤2⋅105) — the number of elements in ss and the desired number of elements in tt, respectively.

The second line of the input contains exactly nn integers s1,s2,…,sns1,s2,…,sn (1≤si≤2⋅1051≤si≤2⋅105).

Output

Print kk integers — the elements of array tt such that you can cut out maximum possible number of copies of this array from ss. If there are multiple answers, print any of them. The required array tt can contain duplicate elements. All the elements of tt (t1,t2,…,tkt1,t2,…,tk) should satisfy the following condition: 1≤ti≤2⋅1051≤ti≤2⋅105.

这个题wa19case,快wa哭惹,结果yl跟我说可能我的二分结束条件把最优解咔了,好吧,可能我二分理解得不够透彻,我改~!

这个题找k个重复次数的数   一个数最多重复n次最少重复1次。那我们就二分找有重复x次的数只要达到了k个 找这个x

#include<bits/stdc++.h>
using namespace std;
int n,k;
int a, b[200000+5];
bool Find(int x)//查找重复x次
{
    int ans = 0;
    for (int i = 1; i <= 200000; i++)
        ans += b[i] / x;
    return (ans>=k);//如果重复x次的>k就 true 
}
int main()
{
    cin >> n >> k;
    for (int i = 1; i <= n; i++)
    {
        cin >> a;
        b[a]++;
    }
    int l = 1, r = n;
    while (l< r)//二分查找
    {
        int mid = (l + r + 1) / 2;
        if (Find(mid))
        {
            l = mid;  //找到>k个的是重复l次的
        }
        else
         r = mid-1;
    }
    int cnt=0;
    for (int i = 1; i <= 200000; i++)
    {
        while(b[i] >= l && cnt < k)//可能同一个数重复多个l次
        {
            cout << i << ' ';
            b[i] -= l ;
            cnt++;
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值