Codeforces Round #702 (Div. 3)ABCEF

A. Плотный массив
ограничение по времени на тест2 секунды
ограничение по памяти на тест256 мегабайт
вводстандартный ввод
выводстандартный вывод
Поликарп называет массив плотным, если в любой паре двух соседних элементов больший элемент не более чем в два раза превышает меньший. Более формально, для любого () должно быть выполнено условие:

Например, массивы , и — плотные. А массивы , , — нет.

Вам дан массив , состоящий из целых чисел. Какое минимальное количество чисел необходимо добавить в массив, чтобы он стал плотным? Вставлять числа можно в любое место массива. Если массив уже является плотным, то числа добавлять не надо.

Например, если , то ответ равен , а сам массив после вставки в него элементов может выглядеть так: (есть и другие оптимальные способы построить плотный массив ).

Входные данные
В первой строке содержится одно целое число (). Далее следуют наборов входных данных.

В первой строке каждого набора входных данных находится одно целое число () — длина массива .

Следующая строка содержит целых чисел ().

Выходные данные
Для каждого набора входных данных выведите одно целое число — минимальное количество чисел, которое необходимо добавить в массив, чтобы он стал плотным.

Пример
входные данныеСкопировать
6
4
4 2 10 1
2
1 3
2
6 1
3
1 4 2
5
1 2 3 4 3
12
4 31 25 50 30 20 34 46 42 16 15 16
выходные данныеСкопировать
5
1
2
1
0
3
Примечание
Первый набор входных данных разобран в условии.

Во втором наборе входных данных можно вставить один элемент, .

В третьем наборе входных данных можно вставить два элемента, .

В четвертом наборе входных данных можно вставить один элемент, .

В пятом наборе входных данных массив уже плотный.

思路 从大数开始 一直除2 向上取整就行

#include<bits/stdc++.h>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
ll read(){ll res = 0, ch, flag = 0;if((ch = getchar()) == '-')flag = 1;else if(ch >= '0' && ch <= '9')res = ch - '0';while((ch = getchar()) >= '0' && ch <= '9' )res = res * 10 + ch - '0';return flag ? -res : res;}
const int maxn =1e6+199 ;
ll sum=0,maxa=-1;
ll n,m,k,w,ans=0,cnt=1;
ll dp[maxn];
double a[maxn];
char b[maxn];
ll mod=1e9+7;
map<int,int>mp;
priority_queue< int,vector<int>,less<int> >q;
 
 
int main()
{
   int T=read();
   while(T--)
   {
       sum=0;
       m=read();
       for(int i=1;i<=m;i++)
       {
           cin>>a[i];
       }
 
       for(int i=2;i<=m;i++)
       {
          if(a[i]/a[i-1]>2)
           {
               double k=a[i];
               while(k/a[i-1]>2)
               {
                   k/=2;
 
                   sum++;
               }
           }
 
           else if(a[i-1]/a[i]>2)
           {
               double k=a[i-1];
               while(k/a[i]>2)
               {
 
                   k/=2;
 
                   sum++;
               }
           }
 
       }
 
       cout<<sum<<endl;
   }
    return 0;
}

B. Сбалансированные остатки
ограничение по времени на тест2 секунды
ограничение по памяти на тест256 мегабайт
вводстандартный ввод
выводстандартный вывод
Вам дано число n (делящееся на 3) и массив a[1…n]. За один ход вы можете увеличить любой из элементов массива на единицу. Формально, вы выбираете индекс i (1≤i≤n) и заменяете ai на ai+1. Вы можете выбирать один и тот же индекс i неоднократно для разных ходов.

Обозначим за c0, c1 и c2 количества чисел из массива a которые имеют остаток 0, 1 и 2 при делении на число 3 соответственно. Скажем, что массив a имеет сбалансированные остатки, если c0, c1 и c2 равны между собой.

Например, если n=6 и a=[0,2,5,5,4,8], то возможна следующая последовательность ходов:

изначально c0=1, c1=1 и c2=4, эти величины не равны между собой. Увеличим a3, теперь массив a=[0,2,6,5,4,8];
c0=2, c1=1 и c2=3, эти величины не равны между собой. Увеличим a6, теперь массив a=[0,2,6,5,4,9];
c0=3, c1=1 и c2=2, эти величины не равны между собой. Увеличим a1, теперь массив a=[1,2,6,5,4,9];
c0=2, c1=2 и c2=2, эти величины равны между собой, значит, массив a имеет сбалансированные остатки.
Найдите, какое минимальное количество ходов необходимо сделать, чтобы массив a имел сбалансированные остатки.

Входные данные
В первой строке содержится одно целое число t (1≤t≤104). Далее следуют t наборов входных данных.

В первой строке каждого набора входных данных находится одно целое число n (3≤n≤3⋅104) — длина массива a. Гарантируется, что число n делится на 3.

Следующая строка содержит n целых чисел a1,a2,…,an (0≤ai≤100).

Гарантируется, что сумма n по всем наборам входных данных не превосходит 150000.

Выходные данные
Для каждого набора входных данных выведите одно целое число — минимальное количество ходов, которые надо совершить, чтобы массив a имел сбалансированные остатки.

Пример
входные данныеСкопировать
4
6
0 2 5 5 4 8
6
2 0 2 1 0 0
9
7 1 3 4 2 10 3 9 6
6
0 1 2 3 4 5
выходные данныеСкопировать
3
1
3
0
Примечание
Первый набор входных данных разобран в условии.

Во втором наборе входных данных необходимо сделать один ход для i=2.

В третьем наборе входных данных необходимо сделать три хода:

первый ход: i=9;
второй ход: i=9;
третий ход: i=2.
В четвертом наборе входных данных величины c0, c1 и c2 изначально совпадают, поэтому массив a уже имеет сбалансированные остатки.

模拟

#include<bits/stdc++.h>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
ll read(){ll res = 0, ch, flag = 0;if((ch = getchar()) == '-')flag = 1;else if(ch >= '0' && ch <= '9')res = ch - '0';while((ch = getchar()) >= '0' && ch <= '9' )res = res * 10 + ch - '0';return flag ? -res : res;}
const int maxn =1e6+199 ;
ll sum=0,maxa=-1;
ll n,m,k,w,ans=0,cnt=1;
ll dp[maxn];
ll a[maxn];
char b[maxn];
ll mod=1e9+7;
map<int,int>mp;
priority_queue< int,vector<int>,less<int> >q;
 
 
int main()
{
   int T=read();
   while(T--)
   {
       sum=0;
       n=read();
       int a0,a1,a2;
       a1=a2=a0=0;
       for(int i=1;i<=n;i++)
       {
           a[i]=read();
           if(a[i]%3==1)
            a1++;
           if(a[i]%3==2)
            a2++;
           if(a[i]%3==0)
            a0++;
       }
       k=n/3;
       if(a1>=k)
       {
           sum+=a1-k;
           a2+=sum;
           a1=k;
       }
       if(a2>=k)
       {
           sum+=a2-k;
           a0+=a2-k;
           a2=k;
       }
 
       if(a0>=k)
       {
           sum+=a0-k;
           a1+=a0-k;
           a0=k;
       }
        if(a1>=k)
       {
           sum+=a1-k;
           a2+=a1-k;
           a1=k;
       }
 
       cout<<sum<<endl;
   }
    return 0;
}

C. Сумма кубов
ограничение по времени на тест2 секунды
ограничение по памяти на тест256 мегабайт
вводстандартный ввод
выводстандартный вывод
Вам дано целое положительное число x. Проверьте, представимо ли число x в виде суммы кубов двух целых положительных чисел.

Формально, вам нужно проверить, существует ли два целых числа a и b (1≤a,b), таких что a3+b3=x.

Например, если x=35, то подходят числа a=2 и b=3 (23+33=8+27=35). Если же x=4, то ни одна пара чисел a и b не подходит.

Входные данные
В первой строке находится одно целое число t (1≤t≤100) — количество наборов входных данных. Далее следуют t наборов входных данных.

Каждый набор входных данных состоит из одного целого положительного числа x (1≤x≤1012).

Обратите внимание, что числа в некоторых наборах входных данных не помещаются в 32-битный целочисленный тип, поэтому вы должны использовать как минимум 64-битный целочисленный тип вашего языка программирования.

Выходные данные
Для каждого набора входных данных в отдельной строке выведите:

«YES», если число x представимо в виде суммы кубов двух целых положительных чисел.
«NO» в противном случае.
Вы можете выводить «YES» и «NO» в любом регистре (например, строки yEs, yes, Yes и YES будут распознаны как положительный ответ).

Пример
входные данныеСкопировать
7
1
2
4
34
35
16
703657519796
выходные данныеСкопировать
NO
YES
NO
NO
YES
YES
YES
Примечание
Число 1 не представимо в виде суммы двух кубов.

Число 2 представимо в виде 13+13.

Число 4 не представимо в виде суммы двух кубов.

Число 34 не представимо в виде суммы двух кубов.

Число 35 представимо в виде 23+33.

Число 16 представимо в виде 23+23.

Число 703657519796 представимо в виде 57793+79933.

思路

二分
第一层for循环1e4
因为1e4的三次方为1e12

第二层二分查找
总体 O(还阔以)

#include<bits/stdc++.h>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
ll read(){ll res = 0, ch, flag = 0;if((ch = getchar()) == '-')flag = 1;else if(ch >= '0' && ch <= '9')res = ch - '0';while((ch = getchar()) >= '0' && ch <= '9' )res = res * 10 + ch - '0';return flag ? -res : res;}
const int maxn =1e6+199 ;
ll sum=0,maxa=-1;
ll n,m,k,w,ans=0,cnt=1;
ll dp[maxn];
ll a[maxn];
char b[maxn];
ll mod=1e9+7;
map<int,int>mp;
priority_queue< int,vector<int>,less<int> >q;
 
const ll inf=1e5+512;
int main()
{
   int T=read();
   while(T--)
   {
       n=read();
       int flag=0;
       for(ll i=1;i*i*i<=n;i++)
       {
           ll left=1, right=inf;
           ll mid=(left+right)/2;
 
           while(left<right)
           {
               ll op=mid*mid*mid+i*i*i;
               if(op==n)
               {
                   flag=1;
                   cout<<"YES"<<endl;
                   break;
               }
               else
               {
                   if(op>n)
                    right=mid;
                   else
                    left=mid+1;
 
                   mid=(left+right)/2;
               }
           }
 
           if(flag==1)
            break;
       }
       if(!flag)
        printf("NO\n");
   }
    return 0;
}

E. Случайная победа
ограничение по времени на тест2 секунды
ограничение по памяти на тест256 мегабайт
вводстандартный ввод
выводстандартный вывод
В Берляндии проводится чемпионат, в котором участвует n игроков. У игрока с номером i есть ai (ai≥1) фишек.

Чемпионат состоит из n−1 игры, которые проводятся по следующим правилам:

в каждой игре выбирается два случайных игрока с ненулевым количеством фишек;
победителем игры считается игрок, у которого больше фишек (при равенстве победитель выбирается случайно);
победивший игрок забирает себе все фишки проигравшего.
Последний игрок с ненулевым количеством фишек считается победителем чемпионата.

Все случайные решения, которые принимаются во время чемпионата, принимаются равновероятно и независимо.

Например если n=4, a=[1,2,4,3], то один из вариантов развития игры следующий (могли быть и другие варианты):

во время первой игры были выбраны первый и четвертый игроки. Количество фишек у четвертого игрока больше, поэтому он забирает фишки первого игрока. Теперь a=[0,2,4,4];
во время второй игры были выбраны четвертый и третий игроки. Количество фишек у них однаково, но случайным образом третий игрок стал победителем. Теперь a=[0,2,8,0];
во время третьей игры были выбраны второй и третий игроки. Количество фишек у третьего игрока больше, поэтому он забирает фишки второго игрока. Теперь a=[0,0,10,0];
третий игрок объявляется победителем чемпионата.
Победители чемпионата получат именные призы. Поэтому судьи хотят заранее узнать, какие игроки имеют шанс на победу, то есть, имеют ненулевую вероятность выиграть чемпионат. Вам было поручено найти всех таких игроков.

Входные данные
В первой строке находится одно целое число t (1≤t≤104) — количество наборов входных данных. Далее следуют t наборов входных данных.

Первая строка каждого набора входных данных состоит из одного целого положительного числа n (1≤n≤2⋅105) — количества игроков в чемпионате.

Во второй строке каждого набора входных данных находятся n целых положительных чисел a1,a2,…,an (1≤ai≤109) — количества фишек у игроков.

Гарантируется, что сумма n по всем наборам входных данных не превышает 2⋅105.

Выходные данные
Для каждого набора входных данных выведите количество игроков, которые имеют ненулевую вероятность выиграть чемпионат. На следующей строке выведите номера этих игроков в возрастающем порядке. Игроки пронумерованы начиная с единицы в порядке следования во входных данных.

Пример
входные данныеСкопировать
2
4
1 2 4 3
5
1 1 1 1 1
выходные данныеСкопировать
3
2 3 4
5
1 2 3 4 5

思路
贪心
要求存在胜利希望的人
我们可以升序排好
从后面开始
如果这个人 把前面的人都赢完(随便,靠偷袭,靠骗)>后面的人的牌子
那么这个人就可以赢
反之 你把自己小的都拿完了 还比人家小 那你靠什么赢 靠偷袭???

#include<bits/stdc++.h>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
ll read(){ll res = 0, ch, flag = 0;if((ch = getchar()) == '-')flag = 1;else if(ch >= '0' && ch <= '9')res = ch - '0';while((ch = getchar()) >= '0' && ch <= '9' )res = res * 10 + ch - '0';return flag ? -res : res;}
const int maxn =1e6+199 ;
ll sum=0,maxa=-1;
ll n,m,k,w,ans=0,cnt=1;
ll dp[maxn];
//ll a[maxn];
int b[maxn];
ll mod=1e9+7;
map<int,int>mp;
 
typedef struct node{
    int x;
    int h;
}ss;
ss a[maxn];
bool cmp(ss a,ss b)
{
 
        return a.x<b.x;
 
}
int main()
{
   n=read();
   while(n--)
   {
       priority_queue< int,vector<int>,greater<int> >q;
       m=read();
       for(int i=1;i<=m;i++)
       {
           a[i].x=read();
           a[i].h=i;
       }
        sort(a+1,a+1+m,cmp);
        for(int i=1;i<=m;i++) dp[i]=dp[i-1]+a[i].x;
        a[m+1].x=-1000;
       for(int i=m;i>=1;i--)
       {
           if(dp[i]>=a[i+1].x)
            q.push(a[i].h);
           else
            break;
       }
       cout<<q.size()<<endl;
       while(q.size())
       {
           cout<<q.top()<<' ';
           q.pop();
       }
       cout<<endl;
 
   }
    return 0;
}

F. Уравняй массив
ограничение по времени на тест2 секунды
ограничение по памяти на тест256 мегабайт
вводстандартный ввод
выводстандартный вывод
Поликарпу подарили массив a длины n. Поликарп считает массив красивым, если существует такое число C, что каждое число встречается в массиве либо ноль, либо C раз. Поликарп хочет удалить из массива a некоторые элементы, чтобы сделать массив красивым.

Например, если n=6 и a=[1,3,2,1,4,2], то возможны следующие варианты сделать массив a красивым:

Поликарп удаляет элементы на позициях 2 и 5, массив a становится равным [1,2,1,2];
Поликарп удаляет элементы на позициях 1 и 6, массив a становится равным [3,2,1,4];
Поликарп удаляет элементы на позициях 1,2 и 6, массив a становится равным [2,1,4];
Помогите Поликарпу определить: какое минимальное количество элементов необходимо удалить из массива a, чтобы сделать его красивым.

Входные данные
В первой строке находится одно целое число t (1≤t≤104) — количество наборов входных данных. Далее следуют t наборов входных данных.

Первая строка каждого набора входных данных состоит из одного целого числа n (1≤n≤2⋅105) — длины массива a.

Во второй строке каждого набора входных данных находятся n целых чисел a1,a2,…,an (1≤ai≤109) — массив a.

Гарантируется, что сумма n по всем наборам входных данных не превышает 2⋅105.

Выходные данные
Для каждого набора входных данных выведите одно целое число — минимальное количество элементов, которые необходимо удалить, что сделать массив a красивым.

Пример
входные данныеСкопировать
3
6
1 3 2 1 4 2
4
100 100 4 100
8
1 2 3 3 3 2 6 6
выходные данныеСкопировать
2
1
2

题目大意
删数字
删到所有数字出现次数一样
求最小次数

思路

暴力
对每一种次数都进行一次模拟就可以

#include<bits/stdc++.h>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
ll read(){ll res = 0, ch, flag = 0;if((ch = getchar()) == '-')flag = 1;else if(ch >= '0' && ch <= '9')res = ch - '0';while((ch = getchar()) >= '0' && ch <= '9' )res = res * 10 + ch - '0';return flag ? -res : res;}
const int maxn =1e6+199 ;
ll sum=0;
ll n,m,k,w,ans=0,cnt=1;
ll dp[maxn];
ll a[maxn];
int b[maxn];
ll mod=1e9+7;

int main()
{
   n=read();
   while(n--)
   {
       sum=0;
       m=read();
vector<ll> qq;
       set<ll>p;
       ll maxa=1000000;
       for(int i=1;i<=m;i++)
       {
           cin>>a[i];
       }
        sort(a+1,a+1+m);
        ll t=1;
        a[m+1]=0;
        for(int i=1;i<=m+1;i++)
        {
            if(a[i]!=a[t])
            {

                qq.push_back(i-t);
                p.insert(i-t);
                 t=i;
            }
        }

        for(auto i :p)
        {
            sum=0;

            for(auto s :qq)
            {
                if(i>s)
                    sum+=s;
                else
                    sum+=s-i;
              
            }
            maxa=min(maxa,sum);
        }

        cout<<maxa<<endl;
   }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

牛郎恋刘娘,刘娘念牛郎

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

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

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

打赏作者

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

抵扣说明:

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

余额充值