アルゴリズムコンペティションのご紹介【コードフーフコレクション上級編 335問】(MT2101-2125)

アルゴリズムコンペティションのご紹介【Code Hoof Collection 上級編 335問】(MT2201-2225)



序文

ここに画像の説明を挿入

なぜ急にアルゴリズムを学びたくなるのですか?

> より「公式な」言語で、アルゴリズムはコンピュータ サイエンスのすべての分野にとって重要であるため。コンピューター サイエンスのほとんどの下位分野では、アルゴリズムの基礎を理解し、アルゴリズムと連携するデータ構造に関する知識が、実際の作業を完了するために不可欠です。
>しかし、実務的な観点から言えば、大学院入試や就職活動の時代が近づいているので(ಥ_ಥ)、どちらの道をたどっても、それなりに豊富なアルゴリズムの知識が必要になることは必至です。アルゴリズムの構想が生まれました. , アルゴリズムコンペは私のような初心者にはほとんど難しいかもしれませんが, それでも挑戦したい. 結局, 夢はまだあります. 実現したらどうなりますか? ~( ̄▽ ̄~)~

ここに画像の説明を挿入


質問をブラッシングするためのソフトウェアとして Codeclip を選んだ理由は何ですか?

コードフーフセットは、 National College of Computer Teaching and Industrial Practice Resource Construction Expert Committee (TIPCC) の指導の下で構築されています。TIPCC は、国内の主要大学のコンピューター部門と清華大学出版局の強力なリソースに依存してコンピューターを提供しています。学習愛好家は、包括的で信頼できるコンピューター演習を提供します。
ここに画像の説明を挿入


目次

1. MT2101 竹ネズミとメロンの種

(1) タイトルの説明
今日、Xiaoma の 2 人の兄弟は、竹のネズミにメロンの種を与える予定です。竹ネズミは一列に並んでおり、兄弟は竹ネズミの重さに応じてメロンの種の数を判断します。

i 番目のタケネズミの重量は a であり、メロンの種を配布する際には、以下の要件を満たす必要があります: 1.
隣接するタケネズミのうち、背の高い方がメロンの種を多く持っている必要があります. 重量が同じ場合は、数彼らが受け取るメロンの種の数は等しくなければなりません。
2. 各タケネズミには少なくとも 1 つのメロンの種があります。
3. 資金が限られているため、条件 1 と 2 を満たすことを前提に、メロンの種をできるだけ少なく配布します。

フォーマット

入力形式:
最初の行は、タケネズミの数を示す整数 n です。
2 行目には、タケネズミの体重を表す n 個の整数があります。
.出力
形式: 準備するメロンの種の最小数。

サンプル1

入力:
5
3 4 5 4 3.
出力
: 9

(2) 参照コード


#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long ll;
int ai[N],ao[N];
ll res[N];
int main()
{
    
    
  int n,min_pt,sum=0;
   cin >> n;
  for (long i = 0; i < n; i++)
 {
    
    
 cin >> ai[i];
 if (ai[i] < ai[min_pt])
 min_pt = i;
 }
 ao[min_pt] = 1;
 for (long i = min_pt; i < n - 1; i++)
 if (ai[i] < ai[i + 1]) ao[i + 1] = ao[i] + 1;
 else if (ai[i] > ai[i + 1])
 {
    
    
 ao[i + 1] = 1;
 if (ao[i] <= 1)
 {
    
    
 long nt = i;
 do {
    
    
 ao[nt]++;
 nt--;
 if (((ao[nt] > ao[nt + 1]) && (ai[nt] > ai[nt + 1])) ||((ao[nt] == ao[nt + 1]) && (ai[nt] == ai[nt + 1])))
 break;
 } while (ai[nt] >= ai[nt + 1]);
 }
 }
 else ao[i + 1] = ao[i];
 for (long i = min_pt; i > 0; i--)
 if (ai[i] < ai[i - 1]) ao[i - 1] = ao[i] + 1;
 else if (ai[i] > ai[i - 1])
 {
    
    
 ao[i - 1] = 1;
if (ao[i] <= 1) {
    
    
 long nt = i;
 do{
    
    
 ao[nt]++;
 nt++;
 if (((ao[nt] > ao[nt - 1]) && (ai[nt] > ai[nt - 1])) ||((ao[nt] == ao[nt - 1]) && (ai[nt] == ai[nt - 1])))
 break;
 } while (ai[nt] >= ai[nt - 1]);
 }
 }
 else ao[i - 1] = ao[i];
 for (long i = 0; i < n; i++) sum += ao[i];
 cout << sum << endl;
}



2. MT2102 竹ネズミとメロンの種 (2)

(1) タイトルの説明

Xiaoma 兄弟は、一度に m 個のメロンの種が入った qiaqia メロンの種を 1 パック購入し、これらのメロンの種を n 匹のタケネズミに配布したいと考えています。

竹ネズミにはそれぞれメロンの種の期待値があり、その期待値が満たされない場合、竹ネズミは怒ります.竹ネズミの怒りの程度は、メロンの種の数の2乗に等しくなります.少なくなります。

シャオマ兄弟は、竹ネズミの怒りの合計を最小限に抑えるために、キャンディーを合理的に配布する必要があります。

フォーマット

入力形式:
最初の行の 2 つの整数 m と n。
2 行目には n 個の整数が含まれており、これは竹ネズミの期待値を表しています。
.出力
形式: 怒っているタケネズミの最小総数を整数で出力します。

サンプル1

入力:
10 4
4 5 2 3.
出力
: 4

(2) 参照コード

import time
from typing import List, Tuple
from collections import deque, Counter
from queue import PriorityQueue
import math
from functools import lru_cache
import random
import copy
import sys

sys.setrecursionlimit(99999999)


def main():
    a, b = map(int, input().split())
    arr = list(map(int, input().split()))
    arr.sort()

    tot = sum(arr)
    tot -= a
    cnt = b
    ans = []
    for v in arr:
        avg = tot // cnt
        x = tot % cnt
        if v <= avg:
            ans.append(v)
            tot -= v
        else:
            if x > 0:
                ans.append(avg + 1)
                tot -= (avg + 1)
            else:
                ans.append(avg)
                tot -= avg
        cnt -= 1

    val = 0
    for v in ans:
        val += v ** 2

    print(val)


if __name__ == '__main__':
    main();

3. MT2103 水温調整

(1) タイトルの説明
シャオマ兄弟の家の浴槽には冷水用の蛇口と温水用の蛇口があり、流出する水の温度はそれぞれ t と tz であり、その流量は最大で毎秒 a 単位と a2 単位です。 Оから最大流量まで任意の整数速度に調整できます。2 つの蛇口の流量が y と y2 (0≤g1,32 ≤10) の場合、最終的な水温は

ここに画像の説明を挿入

ここで、2 つの蛇口の流量が満たされるように調整する必要があります:
1. 最終的な水温が t0 を下回らないこと;
2. 前項を満たす前提で、水温ができるだけ t0 に近いこと;
3.総流量は、前項の前提で可能な限り大きく満足しています。


フォーマット

入力形式: 5 つの整数 t1, t2,C1, 02, to; 1<t1≤to≤t2≤10R; 1≤Z1, 2 ≤106 の行.
出力
形式: y1 と y2 を表す 2 つの数値の行を出力します。

サンプル1

入力: 10 70 100 100 25.
出力
: 99 33

述べる:

データ範囲には十分注意してください。

(2) 参照コード

#include<bits/stdc++.h>
using namespace std;
int t1,t2,x1,x2,t0;
double best=0x3f3f3f3f,t;
pair<int,int> ans;
int main()
{
    
    
	cin>>t1>>t2>>x1>>x2>>t0;
	double y1=x1,y2=x2;
	while(y1>=0&&y2>=0)//坑点一:这里是“>=”而不是“>”
	{
    
    
		t=double(t1*y1+t2*y2)/(y1+y2);//坑点二:别忘了转double
		if(t<t0) {
    
    y1--; continue;}//先考虑温度高的情况
		if(t-t0<best) best=t-t0,ans.first=y1,ans.second=y2;
		//坑点三:这里如果写成if(t<best)best=t的话会在精度上出问题
		y2--;//最后考虑温度低的情况
	}
	cout<<ans.first<<' '<<ans.second<<endl;
	return 0;
}


4. MT2104 活動アレンジ

(1) タイトルの説明
兄弟 Xiaoma は、会社のホールを再び処理するように割り当てられました. 会社にはホールが 1 つしかありませんが、開催する必要がある活動がたくさんあるため、事前に予約が必要です. 会社には n 部門があり、部門ごとにイベントを開催します。各部門は、ホールを使用する予定の時間間隔(a、b)(オープン間隔)を小馬兄弟に報告し、小馬兄弟はこの情報に基づいて調整します.一度に1つのイベントのみを開催できます.次のアクティビティに進むには、完了している必要があります。

シャオマ兄弟はできるだけ多くのイベントを満足させたいので、イベントの手配をお願いします。


フォーマット

入力形式:
1 行目の整数 n で、部門数を表します。
次の n 行は、それぞれ 2 つの整数 a、b を持ち、時間間隔を表します。
・出力
形式:保持できるイベントの最大数を表す整数を出力します。

例 1:

入力
4
1 3
4 6
2 5
1 7.
出力
2

(2) 参照コード

#include<bits/stdc++.h> 

using namespace std;

typedef pair<int,int> PII;
PII t[500010];

bool cmp(PII a,PII b){
    
    
    return a.second<b.second;
}


int main( )
{
    
    
    int n;
    cin >> n;
    int l,r;
    for(int i=1;i<=n;i++){
    
    
        scanf("%d%d",&l,&r);

        t[i] = make_pair(l,r);
    }
    sort(t+1,t+1+n,cmp);

    r = t[1].second;
    int ans = 1;
    for(int i=2;i<=n;i++){
    
    
        if(r<=t[i].first){
    
    
            r = t[i].second;
            ans++;
        }
    }
    cout << ans <<endl;
    
    return 0;
}

5. MT2105 デザートサプライ

(1)タイトル説明
ここに画像の説明を挿入


フォーマット

入力形式:
行 1: スペースで区切られた 2 つの整数: C と L
行 2...C+1: 各行は、下位 i の甘さの要件を記述するために 2 つの整数を使用します: l と Ti
行 C+2....C +L+1: 行 1 特定のデザートの甘さと数を表す 2 つの整数: u; と numi
.
出力形式: 整数を含む 1 行で、最も多くの人にお気に入りのデザートを食べさせることができる人の数を示します。

サンプル1

入力:
3 2
3 10
2 5
1 5
6 2
4 1.
出力
: 2

(2) 参照コード

#include <bits/stdc++.h>
using namespace std;
string a[105];
int n,m;
int b[100005],c[105],d[105];
int main()
{
    
    
cin>>n>>m;
int i,j,t,x=0,y=0;
for(i=0;i<n;i++) cin>>b[i];
sort(b,b+n);
for(i=0;i<m;i++) cin>>a[i];
for(i=0;i<m;i++) c[i]=1;
for(i=0;i<m&&(c[i]!=-1);i++)
{
    
    
for(j=i+1;j<m;j++)
{
    
    
if(a[j]==a[i])
{
    
    
c[i]++;
c[j]=-1;
}
}
}
j=0;
for(i=0;i<m;i++)
{
    
    
if(c[i]>0)
{
    
    
d[j]=c[i];
j++;
}
}
sort(d,d+j);
for(i=0,t=j-1;t>=0;i++,t--) x+=d[t]*b[i];
for(i=n-1,t=j-1;t>=0;i--,t--) y+=d[t]*b[i];
cout<<x<<" "<<y;
return 0;
}


6. MT2106 フィボナッチ数列の組み合わせ

(1) タイトルの説明
正の整数 n が与えられたとき、フィボナッチ数の合計が n になる最小の数を返す関数 MinFibonacciNumbers を記述してください。

フィボナッチ数列:
F1=1
F2=1
Fn= Fn-1+Fn-2, n > 2 は、
解が存在することを保証します。

フォーマット

入力形式: 1 行目に正の整数 n を入力
出力
形式: 条件を満たす最小数を出力

サンプル1

入力: 19.
出力
: 3

(2) 参照コード


arr = [1,1]
while arr[-1] < 10**9:
    arr.append(arr[-1]+arr[-2])


def main():
    #code here
    tot = int(input())
    cnt = 0
    for v in arr[::-1]:
        while v <= tot:
            tot -= v
            cnt += 1
        if tot == 0:
            break
    print(cnt)

if __name__ == '__main__':
    main();

7. MT2107のペアリング

(1) タイトルの説明
Xiaoma 兄弟には m 人の部下がいて、a[i] で表されるこれらの m 人の居住地の住所を知っています。彼は今、k グループを集めたいと考えています。形成された場合、それらは同じ場所、つまり同じ座標の下に移動する必要があります。

ただし、これらの部下は移動するためにお金を使う必要があり、費やされるお金は移動距離に比例します。チームを編成すると、9-2=7 の費用がかかります。

Xiaoma 兄弟は、資金の合計額が最小になることを望んでいます;
1 人の部下が同時に 2 つのグループに参加することはできません;
データは、α[i] が厳密に昇順で配置されることを保証します。

フォーマット

入力形式:
1 行目に正整数 m、
2 行目に k を入力、スペース区切りで m 個の整数を入力出力形式
:最小コストを出力

サンプル1

入力:
5 2
1 3 4 6 12.
出力
: 4

述べる:

ヒント 1≤a[i]≤1e6、1≤k*2≤m≤1e4

(2) 参照コード

#include<bits/stdc++.h> 

using namespace std;

long long spents=0,min_s=10000000000;
void backtracking(vector<int>& vec, int start_index,int k,int flag){
    
    
if(k==0){
    
    
// cout‹‹spents‹‹"ss \n";
if(spents<min_s){
    
    
    min_s=spents;
// cout‹‹min_s‹<"min_s\n";
if(min_s<=flag){
    
    
// cout<‹"clear \n".
    vec. clear();
}
}
return;
}
if (spents<min_s){
    
    
    for(int i=start_index;i<vec.size();++i){
    
    
        if (vec[i]>min_s) continue;
        spents+=vec[i];
        backtracking(vec, i+2,k-1, flag);
        spents-=vec[i];}
}
return;}
int main( )
{
    
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, num, pre, k, flag=0, count_k=0;
vector<int> dest_len;
multiset<int> dest_set;
cin>>n>>k;
cin>>pre;
for(int i=1;i<n;++i){
    
    
    cin>>num;
    dest_len.push_back(num-pre);
    dest_set.emplace(num-pre);
    pre=num;}
    vector<int> t=dest_len;
    for(auto c:dest_set){
    
    
        flag+=c;
        ++count_k;
        if(count_k==k) break;
    }
    backtracking(dest_len,0,k,flag);

    cout<<min_s;
    return 0;
}


8. MT2108 シーケンス セグメンテーション

(1) タイトルの説明
長さ IV の特定の正の整数シーケンス Ai について、それをいくつかの連続するセグメントに分割する必要があり、各セグメントの合計が M を超えない (M に等しくなる可能性がある)、セグメントの数を尋ねる少なくとも要件を満たすように分割できます。

フォーマット

入力形式:
行 1 には、シーケンス A の長さと各和の最大値を表す 2 つの正の整数 N、M が含まれます. 行 2 には、タイトルに記載されているように、NⅣ スペースで区切られた正の整数 A が含まれます.
.出力
形式: 正の整数、最小のセグメント番号を出力します。

サンプル1

入力:
5 6
4 2 4 5 1.
出力
: 3

(2) 参照コード


def main():
    #code here
    N,M=map(int, input () .split ())
    num=list(map(int, input () .split ()))
    s=0
    res=1
    for i in range(N):
        if s+num[i]<=M:
            s+=num[i]
        else:
            res+=1 
            s=num[i]
    print(res)
    pass


if __name__ == '__main__':
    main();

9. MT2109 スペル番号

(1) 話題の説明
数学一家の数学者であるシャオマは、幼い頃から数学に深く興味を持ち、回文数の対称性に恋をした。

そのため、小馬兄弟は新聞紙から無作為に切り取り、単位の長さに応じて短冊を格子状に切り取り、各格子は 1 桁の数字または空白のいずれかであり、空白の格子に任意の 1 桁の数字を書きます。 、そしてこれらのグリッド(空のグリッドに書かれた数グリッドを含む)を回文数に配置します(すべてのグリッドを使い果たす必要はありません)。

Xiaoma 兄弟は、彼が綴ることができる最大の回文は何ですか?

フォーマット

入力形式: 最初の行の文字列, 小馬兄弟が切り取った紙片を表し, 文字列が数字とスペースのみで構成されていることを確認. 出力形式 : 小馬兄弟が綴ることができる回文の
最大
を表す整数 (先行ゼロは考慮されません)

サンプル1

入力: 11 22 33.
出力
: 93211239

述べる:

その中で: 1≤string length≤10 の 6 回

(2) 参照コード

#include <bits/stdc++.h>
 #define int long long
 #define end END
 #define endl "\n"
 #define debug(x) cout << "*----" << x << "----*" << endl
 #define show(x) cout << #x "=" << x << endl
 using namespace std;
 typedef long long ll;
 const int N = 3e4 + 7;
 const int INF = 0x3f3f3f3f;
 const int mod = 1e9 + 7;
 string s[N];
 int trie[N * 10][26];
 int tot;
 bool end[N*10];
 void insert(int x)
 {
    
    
 int p = 0;
 for (int i = 0; i <s[x].size(); i++) {
    
    
 int ch = s[x][i] - 'a';
 if (trie[p][ch] == 0)
 trie[p][ch] = ++tot;
 p = trie[p][ch];
 }
 end[p] = 1;
 }
 int g[26][26];
 bool ask(int x)
 {
    
    
 memset(g, 0, sizeof g);
 int p = 0;
 for (int i = 0; i < s[x].size(); i++) {
    
    
 int ch = s[x][i] - 'a';
 if (end[p])
 return false;
 for (int j = 0; j < 26; j++) {
    
    
 if (j != ch && trie[p][j]) {
    
    
        if(g[ch][j]>0) return false;
        }
}
for(int j=0;j<26;j++){
    
    
     if (j != ch && trie[p][j]) {
    
    
 g[ch][j] = -1;
 g[j][ch] = 1;
 vector<int> a, b;
 for (int k = 0; k < 26; k++) {
    
    
 if (g[j][k] == -1) {
    
    
 g[ch][k] = -1;
 g[k][ch] = 1;
 b.push_back(k);
 }
 if (g[ch][k] == 1) {
    
    
 g[j][k] = 1;
 g[k][j] = -1;
 a.push_back(k);
 }
 }
 for (auto u : a) {
    
    
 for (auto v : b) {
    
    
 g[u][v] = -1;
 g[v][u] = 1;
 }
 }
 }
 }
 p = trie[p][ch];
 }
 return true;
 }
signed main()
 {
    
    
 int n;
 cin >> n;
 int sum=0;
 for (int i = 1; i <= n; i++) {
    
    
 cin >> s[i];
 sum+=s[i].size();
 insert(i);
 }
 if(sum>3e5) while(true);
 if(n>3e4) while(true);
 if(tot>3e5) while(true);

 vector<int> ans;
 for (int i = 1; i <= n; i++) {
    
    
 if (ask(i))
 ans.push_back(i);
 }
 cout << ans.size() << endl;
 for (auto u : ans) {
    
    
 cout << s[u] << endl;
 }
 return 0;
 }



10. MT2110 マージ 01 文字列を削除

(1) タイトルの説明
01 でいっぱいの文字列が与えられた場合、毎回同じ文字 (すべて 0 またはすべて 1) の部分文字列のみを削除してから、文字列をマージできます。部分文字列を削除した後、残りの文字列を並べてマージします。元の注文。

削除ごとに特定のスコアが取得され、その値は I (削除された文字列の長さ)*a+b です。

獲得できる最大スコアを見つけます。

フォーマット

入力形式:
最初の行の整数 t は、テスト グループの数を示します.
各データ セットの最初の行には、n, a, b (1<n ≤100;—100 ≤ a, b ≤100) が含まれます。は文字列の長さ、aとbは計算式の2つのパラメータ 2行目に01文字列を入力 出力形式:
データのグループごとに1つの結果を出力

サンプル1

入力:
3
3 2 0
000
5 -2 5 11001
6
1 -4
100111.
出力: 6 15 -2



(2) 参照コード

#include<bits/stdc++.h> 

using namespace std;
typedef long long ll;
 const int N = 5e6 + 100;
 const int INF = 0x3f3f3f3f;
 const int mod = 1e9 + 7;
 const unsigned long long P = 13131;
 char s[N];
 int ans[N];
 unsigned long long p[N];
 unsigned long long pre[N];
unsigned long long suf[N];
int long long hash1(int l, int r)
 {
    
    
 if (l <= r)
 return pre[r] - pre[l - 1] * p[r - l + 1];
 else
 return suf[r] - suf[l + 1] * p[l - r + 1];
 }
 int main(){
    
    
 scanf("%s", s + 1);
 int n = strlen(s + 1);
 p[0] = 1;
 for (int i = 1; i <= n; i++)
 p[i] = p[i - 1] * P;
 for (int i = 1; i <= n; i++) {
    
    
 pre[i] = pre[i - 1] * P + s[i];
 }
 for (int i = 1; i <= n; i++) {
    
    
 int x = n - i + 1;
 suf[x] = suf[x + 1] * P + s[x];
 }
 for (int i = 1; i <= n; i++) {
    
    
 if (hash1(1, i) == hash1(i, 1))
 ans[i] = ans[i / 2] + 1;
 }
 int sum = 0;
 for (int i = 1; i <= n; i++) {
    
    
 printf("%d%c",ans[i]," \n"[i==n]);
 }
 return 0;
 }

11. MT2111 小さいコードのお兄さんは数字が大好き

(1) トピックの説明
シャオマは数字がとても好きなので、ある日先生を見つけて数字について質問しました。教師は彼に多数の桁数 (250 桁以下) の正の整数 N を与え、コードの弟に k 桁を削除するように依頼しました。正しい順序。Xiaoma 兄弟は、先生が自分のことを難しくしていると感じているので (Xiaoma 兄弟は 1 年生しかいないため)、プログラマーとして与えられた N と k をプログラミングして、構成された新しい数を最小化する解を探すように依頼します。残りの数の。

フォーマット

入力形式:
n (精度の高い正の整数)。先頭の 0 を考慮する必要はありません。
k (削除する桁数)。保証された出力、つまり k が n より小さいビット数。
.出力
形式: 最後に残った最小数。

サンプル1

入力:
175438
4
.
出力: 13

(2) 参照コード

from collections import deque,Counter
from queue import PriorityQueue

def main():
    #code here
    s = str(int(input()))
    k = int(input())
    n = len(s)

    bits = n-k;
    que = PriorityQueue()
    for i in range(n-bits):
        que.put((s[i],i))

    cur_pos = -1
    ans = []
    all_zero = True
    pos = None
    for i in range(n-bits,n):
        que.put((s[i],i))

        while que.queue[0][1] <= cur_pos:
            que.get()

        v,idx = que.get()
        ans.append(v)
        if v!= '0':
            if all_zero:
                pos = len(ans)-1
                all_zero = False
        
        cur_pos = idx
    
    if all_zero:
        print(0)
        return 
    
    print(''.join(ans[pos:]))

if __name__ == '__main__':
    main();


12. MT2112 部分文字列のセグメンテーション

(1) タイトルの説明
Xiaoma 兄弟は、文字列 s と単語 u を持っています. 彼は s をいくつかの部分文字列に分割して、各部分文字列が部分列 w を持つようにしたいと考えています. 彼は、最大でいくつの部分文字列を分離できるかを尋ねました.

フォーマット

入力形式: 1行目は小文字のみの文字列s、2行目は文字列wの合計2行を入力し、1≦wl≦ls≦1×105を満たす。
.出力
形式: 分離できる部分文字列の最大数を表す整数を出力します。

サンプル1

入力:
aaabbbcccabc
abc
.
出力: 2

述べる:

2 つの部分文字列 aaabbbc と ccabc に分けることができ、どちらにもサブシーケンス abc が含まれます。

(2) 参照コード

#include<bits/stdc++.h> 
#include<iostream>
#include<string>

using namespace std;

int main( )
{
    
    
    string s,w;
    cin>>s;
    cin>>w;
    int len_w=w.length();
    int len_s=s.length();
    int i=0,j=0,ans=0;
    while(i!=len_s)
    {
    
    
        if(s[i]==w[j]){
    
    
            j++;
            if(j==len_w)
            {
    
    
                ans++;
                j=0;
            }
        }
        i++;
    }
    cout<<ans<<endl;
    return 0;
}

13.MT2113飛沫インク

(1) タイトルの説明
小馬兄弟には n 枚の絵があり、各絵には数字 ai があり、これは非負の数であり、同じにすることができます。彼はいくつかの絵の数を変更して、n 枚の絵で使用される異なる数が k を超えないようにしたいと考えています. 少なくとも何枚の絵を変更する必要がありますか?

データ範囲 1≤k≤n≤200000。

フォーマット

入力形式:1行目にn、kを2行目にiを入力します。
.出力
形式: 番号を変更する必要がある最小数の画像を出力します。

サンプル1

入力:
5 2
1 1 2 2 5
.
出力: 1

(2) 参照コード

#include<bits/stdc++.h> 

using namespace std;

int n,k;
map<int,int> cnt;
vector<int> a;
int main( )
{
    
    
    cin>>n>>k;
for (int i=1,x;i<=n;++i){
    
    
cin>>x;
if(cnt.count (x))++cnt[x];
else cnt [x]=1;
}
for (map<int,int>::iterator it=cnt.begin();it!=cnt.end();++it)a.emplace_back(it->second);
sort (a.begin(),a.end ());
if(a.size()<=k){
    
    cout<<0<<endl;return 0;} 
int sum(0);
for (int i=1;i<=k;++i)
sum+=a[a.size()-i];
cout<<n-sum<<endl;
    return 0;
}

14. MT2114 非常に重い銃

(1) タイトル説明
セオベがモンスターと戦っている 目の前に n 体のモンスターがいて、i 番目のモンスターの血液量は ai です。モンスターの場合、彼女には 2 つの攻撃があります。

1.AIの通常攻撃でモンスターを破壊
2.スキルでモンスターを破壊

Ceobe はスキルを最大 k 回しか使用できず、すべてのモンスターを破壊するために少なくとも何回の通常攻撃を使用する必要があるかを知りたいと考えています。

フォーマット

入力形式
1行目にn、kを2行目にaiを入力します。データ範囲 0≤ai、k ≤1091≤n ≤2×105。.
・出力
形式:通常攻撃の最小回数を出力します。

サンプル1

入力:
3 1
4 1 5
.
出力: 5

(2) 参照コード

#include<bits/stdc++.h> 

using namespace std;
int a[200010];
int main( )
{
    
    
    int i,j,k,m,n;
    long long sum=0;
    scanf("%d%d",&n,&k);
    for(i=1;i<=n;i++){
    
    
        scanf("%d",&a[i]);
    }
    sort(a+1,a+n+1);
    for(i=1;i<=n-k;i++){
    
    
        sum+=a[i];
    }
    printf("%lld\n",sum);
    return 0;
}

15.川を渡るMT2215ボート

(1) タイトルの説明

n 人々は川を渡りたいと思っていますが、今はボートが 1 隻しかありません (船頭のいる)。ボートは、(船頭に関係なく) 毎回川を渡って最大 2 人を運ぶことができ、最大積載重量 t を持っています。ボートが往復する最小回数を計算してください。

フォーマット

入力形式:
1 行目に 2 つの整数 n と t を入力 (0<n ≤ 105, 0<t<232 ) 2 行
目に各人の体重を表す n 整数 (範囲: [1,232-1]、すべて未満) t ) .
出力
形式: 整数を出力します

サンプル1

入力:
4 3
3 2 2 1.
出力
: 3

(2) 参照コード

 #include <bits/stdc++.h>

 using namespace std;

 int main() {
    
    
 cin.tie(NULL)->ios_base::sync_with_stdio(false);
 int n, m;
 cin >> n >> m;
 vector<int> v(n);

 for (auto &x : v)
 cin >> x;

 multiset<int> s;

 for (auto x : v)
 s.insert(x);

 int ans = 0;

 while (!s.empty()) {
    
    
 auto x = *s.rbegin();
 s.erase(s.find(x));

 if (!s.empty() && s.upper_bound(m - x) != s.begin())
 s.erase(prev(s.upper_bound(m - x)));

 ++ans;
 }
 cout << ans << endl;

 return 0;
 }


16. MT2116 テーブル脚

(1) タイトル解説
n脚のテーブルがあります。i 番目の脚の長さは l です。

ここで、テーブルを安定させるためにいくつかの脚を削除する必要があります。i 番目の脚を削除するには d が必要です。のエネルギー。

安定条件とは、テーブルの脚をいくつか取り除いて k 本の脚がある場合、最も長い脚の数が半数以上になることです。たとえば、テーブルに 5 本の脚がある場合、少なくとも 3 本の脚が最も長くなければなりません。さらに、脚が 1 つしかないテーブルは安定しており、脚が 2 つあるテーブルは安定するために同じ長さでなければなりません。

あなたの仕事は、テーブルが安定し、エネルギーの消費が最小限になるように、脚を取り外すことです。

フォーマット

入力形式:1行目に数字n、2行目にl、3行目にd; 1-4.
.出力
形式: 消費される最小エネルギーを示す数値

サンプル1

入力:
2
1 5
3 2.
出力
: 2

述べる:

1<=n<=1e5, 1<= li<=1e5,1<= d;<=200

(2) 参照コード

 #include <stdio.h>
 #include <stdlib.h>
 #include <string>
 #include <string.h>
 #include <algorithm>
 #include <map>
 #include <vector>
 #include <algorithm>
 #include <vector>
 #include <set>
 #include <queue>
 #include <string>
 #include <unordered_map>
 #include <unordered_set>
 using namespace std;
 #define MAX_SPLAY_NODE_NUM 100005
 struct Node {
    
    
int child[2]; // 左右子节点编号
 int parent; // 父节点编号
 int val; // 节点数值
 long long sum; // 子树和
 int size; // 子树大小
 int dep; // 子树深度
 int flag; // 懒标记i

 void init(int p, int v) {
    
    
child[0] = child[1] = 0;
 parent = p;
 val = v;
 sum = v;
 size = 1;
 dep = 1;
 flag = 0;
}
 } __splay_node_pool[MAX_SPLAY_NODE_NUM];
int __splay_pool_pos = 1;

 class SplayTree {
    
    
 public:
 int __root;
 Node* __pool;
 int& __pool_pos;
 class __init_guard {
    
    
 public:
 __init_guard() {
    
    
__splay_node_pool[0].init(0, 0);
__splay_node_pool[0].size = 0;
__splay_node_pool[0].sum = 0;
}
};

 static __init_guard __guard;
 public:
SplayTree() : __pool_pos(__splay_pool_pos), __root(0),
__pool(__splay_node_pool) {
    
     }

Node& get_node(int idx) {
    
     return __pool[idx]; }

 int get_root() {
    
     return __root; }

 void move(int x, int k) {
    
     __move(x, k); }
 int insert(int val) {
    
    
int u = __root, p = 0;
while (u != 0) {
    
    
 p = u;
__push_down(p);
u = __pool[u].child[val > __pool[u].val];
 }

 u = __pool_pos++;
 if (__pool_pos > MAX_SPLAY_NODE_NUM) {
    
     printf("overflow!!!\n");
return -1; }

if (p != 0) {
    
     __pool[p].child[val > __pool[p].val] = u; }

__pool[u].init(p, val);
 while (p) {
    
     __push_up(p); p = __pool[p].parent; }
__move(u, 0);
 return u; }
int get_kth_idx(int k) {
    
    
 int u = __root;
while (u) {
    
     
    __push_down(u);
 if (__pool[__pool[u].child[0]].size >= k) {
    
     u =__pool[u].child[0]; }
 else if (__pool[__pool[u].child[0]].size + 1 == k) {
    
     return u; }
 else {
    
     k -= __pool[__pool[u].child[0]].size + 1; u =__pool[u].child[1]; }
 }

return 0;
}
 long long get_sum(int idx) {
    
     return __pool[idx].sum; }
 void reverse_flag(int idx) {
    
    
 __push_down_rev(idx, 1);
}
 private:
 void __push_up(int idx) {
    
    
 Node& node = __pool[idx];
node.size = 1 + __pool[node.child[0]].size +__pool[node.child[1]].size;
 node.sum = node.val + __pool[node.child[0]].sum + __pool[node.child[1]].sum;
 node.dep = 1 + max(__pool[node.child[0]].dep,__pool[node.child[1]].dep);
 }

 void __push_down_rev(int idx, int f) {
    
    
 if (!idx) {
    
     return; }
 if (!f) {
    
     return; }
 __pool[idx].flag ^= 1;
 swap(__pool[idx].child[0], __pool[idx].child[1]);
 }

 void __push_down(int idx) {
    
    
 if (__pool[idx].flag) {
    
    
 // 下传区间翻转标记
 __push_down_rev(__pool[idx].child[0], __pool[idx].flag);
 __push_down_rev(__pool[idx].child[1], __pool[idx].flag);
 __pool[idx].flag = 0;
 }
 }
 void __rotate(int x) {
    
    
 int y = __pool[x].parent, z = __pool[y].parent;
 __push_down(y); __push_down(x);

 int k1 = __pool[y].child[1] == x, k2 = __pool[z].child[1] == y;
 __pool[z].child[k2] = x;
 __pool[x].parent = z;
 __pool[y].child[k1] = __pool[x].child[k1^1];
 __pool[__pool[x].child[k1^1]].parent = y;
 __pool[x].child[k1^1] = y;
 __pool[y].parent = x;
 __push_up(y); __push_up(x);
 }
 void __move(int x, int k) {
    
    
 while (__pool[x].parent != k) {
    
    
 int y = __pool[x].parent, z = __pool[y].parent;
if (z != k) {
    
    
if ( (__pool[y].child[1] == x) != (__pool[z].child[1]== y) ) {
    
     __rotate(x); }
 else {
    
     __rotate(y); }
 }
 __rotate(x);
 }
 if (k == 0) {
    
     __root = x; }
 }
 };
 SplayTree::__init_guard SplayTree::__guard;
 struct node {
    
    
 int len, cost;

 bool operator < (const node& o) const {
    
    
 return len < o.len;
 }
 };
 const int N = 100005;
int l[N], d[N];

 int main(){
    
    
 #ifdef TEST
freopen("/Users/grh/Programming/CLionProjects/AlgoCoding/input.txt","r", stdin);
#endif

 int n; scanf("%d", &n);
int len, cost;
 vector<node> v;
 long long tot = 0;

 for (int i = 0; i < n; i++) scanf("%d", l+i);
 for (int i = 0; i < n; i++) scanf("%d", d+i);

 for (int i = 0; i < n; i++) {
    
    
 v.push_back({
    
    l[i], d[i]});
 tot += d[i];
 }
 sort(v.begin(), v.end());

 SplayTree tree; tree.insert(0); // 左边加一个哨兵

 int ii = 0;
 long long mx = 0;
 while (ii < n) {
    
    
 int jj = ii;
 while (jj+1 < n && v[jj+1].len == v[ii].len) {
    
    
 jj++;
 }

 int k = jj-ii + 1;
 k = min(ii, k-1);
 long long s;
 if (k > 0) {
    
    
 int idx1 = tree.get_kth_idx(ii + 1 - k);
 int idx2 = tree.get_kth_idx(ii + 1 - k + 1);
 tree.move(idx1, 0);
 tree.move(idx2, idx1);
 s = tree.get_sum(idx2);
 } else {
    
    
 s = 0;
 }

 for (int i = ii; i <= jj; i++) {
    
    
 tree.insert(v[i].cost); s += v[i].cost;
 }

 mx = max(mx, s);
 ii = jj+1;
 }
 printf("%lld\n", tot - mx);
 return 0;
}




17. MT2117 マキシマム

(1) タイトルの説明
長さ n の整数 s と整数 a が与えられたとき、s の各桁は ∈ [1,9] であり、整数 s は負の場合があります。ここで、挿入後の s が最大になるように、整数 α が s の特定の位置に挿入されます。(マイナス記号の左側には挿入できません)

関数 MAXVALUE、入力パラメータの文字列、挿入値を記述してください。、aを挿入した後に最大sを作成して、上記の関数を完成させます。

フォーマット

入力形式:
1 行目の 2 つの整数 n, z (1 <=n<= 105,1<=C<=9)
2 行目の文字列 s は長さ n の整数を表します
.
出力形式: 長さを出力しますn+1 文字列 s

サンプル1

入力:
3 2
-13
.
出力: -123

(2) 参照コード

#include<bits/stdc++.h>
std::string MAXVALUE(std::string s, int x)
 {
    
    
 bool sg = s[0] == '-';
 bool flag = true;
 for (auto it = s.begin(); it != s.end(); it++) {
    
    
 if (flag) {
    
    
 if (sg && it!= s.begin() && *it > x + '0' || !sg && *it < x
+ '0') {
    
    
 s.insert(it, x + '0');
 flag = false;
 }
 }
 }
 if (flag) {
    
    
 s.push_back(x + '0');
 }
 return s;
 }
 int main( )
 {
    
    
 std::ios::sync_with_stdio(false);
 int n, x;
 std::cin >> n >> x;
 std::string s;
 std::cin >> s;
 std::cout << MAXVALUE(s, x) << std::endl;
 return 0;
 }


18. MT2118 最小文字列

(1) タイトルの説明
'0'、'1'、'2' からなる文字列 S が与えられたとする。隣接する 'O', '1' または '1', '2' の位置を入れ替えることができます (例: '12'-'21'; '01'- '10') 任意の変換後に辞書を出力してください元の文字列 最小の文字列。元の文字列の長さが 105 を超えない。

フォーマット

入力形式: 文字列
.
出力形式: 変換後の辞書式順序が最小の文字列

サンプル1

入力: 100210
.
出力: 001120

述べる:

1≦\S|≦100000

(2) 参照コード

 #include <bits/stdc++.h>
 using namespace std;
 void solve() {
    
    
 string str, res; cin >> str;
 int n = str.length(), one = 0;
 for (int i = 0; i < n; ++i) one += str[i] == '1';
 for (int i = 0; i < n; ++i)
 if (str[i] == '2') {
    
    
 res += string(one, '1');
 for (int j = 0; j < n; ++j)
 if (str[j] != '1')
 res += str[j];
 cout << res << "\n";
 return;
 } else if (str[i] == '0') {
    
    
 int zero = 0, p = i;
 while (p < n && str[p] != '2') zero += str[p++] == '0';
 res += string(zero, '0');
 res += string(one, '1');
 for (int j = p; j < n; ++j) if (str[j] != '1') res +=str[j];
 cout << res << "\n";
 return;
 }
 cout << str << "\n";
 }
 int main() {
    
    
 ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
 solve();
 return 0;
 }


19. MT2219 三国志殺し

(1) タイトルの説明
Xiaoma 兄弟と Xiaob は三国志殺しが大好きです。ゲームでは、各プレイヤーは n 人の将軍を持ち、各将軍には力の値があります。各ラウンドで、各プレイヤーは戦う将軍を選び、力の値が最も高いものが勝ち、将軍は同時に捨て札の山に入ります。小さいbのカードの順番を事前に知っている場合、最大で何ラウンド勝つことができますか?

フォーマット

入力形式:
最初の行には正の整数 n が含まれ、
2 行目には n の正の整数 a が含まれ、これは小さなコードの兄弟の一般を意味します。3 行目には、小さなコードの一般を
表す n の正の整数 b が含まれます

出力形式: 整数、小さなコードを出力

サンプル1

入力:
3
1 2 3
1 2 3.
出力
: 2

(2) 参照コード

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

int i,j,k,n,m,t,a[1000005];
multiset<int> s;

int main() {
    
    
	cin>>n;
	for(i=1;i<=n;i++){
    
    
		cin>>k;
		s.insert(k);
	}
	for(i=1;i<=n;i++) cin>>a[i];
	sort(a+1,a+n+1);
	for(i=n;i>=1;i--){
    
    
		auto it = s.upper_bound(a[i]);
		if(it!=s.end()){
    
    
			s.erase(it);
			t++;
		}
	}
	cout<<t;
	return 0;

}


20. MT2120 果物狩り

(1) タイトルの説明
シャオマ兄弟は今日、たくさんの果物で報われましたが、これらの果物を自分で収穫する必要があります. シャオマ兄弟が果物を1回収穫するのに1分かかります.

ある果樹園には n 種類の果樹があり, それらは数軸上に分布し, 独立座標 a を持っている. 小馬兄弟は最初の果樹の下を歩き始める. i 木から i+1 に行くのに t 時間かかる.木。

Xiaoma 兄弟がこの果樹の下で摘み取ることを選択した場合、最初の 1 分間は a; の実を摘み、2 回目の摘み取りは a; ~ d; の実を摘みます。等々。

しかし、小馬兄弟の時間は限られており、果物を収穫するのに合計時間はわずかです

収穫できる果物の最大数を彼が理解するのを手伝ってください。

フォーマット

入力形式:
1 行目は正の整数 n, t を入力し、
2 行目 n の数値は最初に収穫できる果物 ai の数を表します。
3 行目の n の数字は、ピックごとに削減できるピックの数 d を表します。
4 行目には n-1 個の数値が含まれており、数値間の移動時間 ti を表しています。
.出力
形式: 果物の最大数を数値で出力

サンプル1

入力:
2 12
10 6
2 5
2
.
出力: 37

述べる:

ヒント: すべての変数は正の整数
1<t ≤ 192、1 ≤ n ≤ 25、1 ≤ ai、d、ti ≤ 1e5

(2) 参照コード


 #include<bits/stdc++.h>
 using namespace std;
 int n,m,ct;
 long long ans;
 long long f[30][200005];
 int a[30],d[30],t[30];
 priority_queue<int>q;
 void solve(int w){
    
    
int sum=m-t[w];
 long long rans=0;
 if(sum<0) return ;

 for(int i=1;i<=w;i++){
    
    
 int ct=a[i];
 for(int j=1;j<=sum;j++){
    
    
 q.push(ct);
 ct-=d[i];
 if(ct<0) break;
 }
 }

 while(sum>0 && !q.empty()){
    
    
 rans+=q.top();
 q.pop();
 sum--;
 }
 ans=max(ans,rans);
 while(!q.empty()) q.pop();
 }
 int main(){
    
    
 cin>>n>>m;
 for(int i=1;i<=n;i++) cin>>a[i];
 for(int i=1;i<=n;i++) cin>>d[i];
 for(int i=2;i<=n;i++) cin>>t[i];
 for(int i=3;i<=n;i++) t[i]+=t[i-1];

 for(int i=1;i<=n;i++) solve(i);
 cout<<ans;
 return 0;
 }

21.MT2121電源

(1) タイトルの説明
最近、Xiaoma 兄弟は建設管理ゲームに夢中になりました.ゲーム内の施設は、エネルギーを供給するためにエネルギー塔を必要とします.施設が稼働しているとき、それらは動作するために近くに一定数のエネルギー塔を必要とします.さまざまな施設エネルギータワーが必要. エネルギータワーにリンクできる数と範囲も異なる. 施設のリンク範囲を超えたエネルギータワーは施設にエネルギーを提供できない. 異なる施設は同じエネルギータワーを再利用できる.

現在、Xiaoma 兄弟は長さ n の道路を建設してエネルギー タワーを配置しましたが、エネルギー タワーの建設コストが少し高くなりました. Xiaoma 兄弟は、リソースを収集するのに多くの時間を費やしてエネルギー タワーを建設することを望んでいません. Xiaoma 兄弟は、間隔 [ s,e] を使用して、エネルギー タワーにリンクされた各施設の有効範囲と、各施設に必要なエネルギー タワーの数 t を教えてくれます。すべての施設が稼働します

フォーマット

入力形式:
道路の長さと施設の数を示す 2 つの正の整数 n、b、および
施設のリンク範囲の開始と終了を示す 3 つの正の整数 s、e、t が b の各行に続くおよび必要なエネルギー タワーの数量
.
出力形式: 必要なエネルギー タワーの最小数を示す整数

サンプル1

入力
8 3
1 3 1
4 5
1 3 3 1出力
2

述べる:

1≤n≤105、1≤b<104。
1≤sj≤ej≤n、1≤tj≤ei-Sj+1。

(2) 参照コード

 #include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
 const int maxn = 100005;
 int n, b;
 vector<int> se[maxn];
 vector<int> st[maxn];
 int ans[maxn], len[maxn];
 int main() {
    
    
 cin >> n >> b;
 for(int i = 1; i <= b; i++) {
    
    
 int s, e, t;
 cin >> s >> e >> t;
 se[s - 1].push_back(e);
 st[s - 1].push_back(t);
 len[s - 1]++;
 }
 for(int i = 0; i <= n; i++) {
    
    
 if(i != 0) ans[i] = max(ans[i - 1], ans[i]);
 for(int j = 0; j < len[i]; j++) {
    
    
 ans[se[i][j]] = max(ans[se[i][j]], ans[i] + st[i][j]);
 int tt = ans[se[i][j]] - se[i][j];
 for(int k = i + 1; k < se[i][j]; k++)
 ans[k] = max(ans[k], tt + k);
 }
 
 }
 cout << ans[n];
 return 0;
 }


22. MT2122 リトルコード兄弟の新しいチェッカーゲーム

(1) タイトルの説明
シャオマ兄弟はチェッカーが好きです。チェッカー ゲームは、合計 n ポジション (1 ~ n) の直線上にあり、各ポジションには 3 つの状態があります。0 はチェスの駒がないことを意味し、1 は赤のチェスの駒を意味し、2 は青のチェスの駒を意味します。開始点 (座標 0) にはピースがありません。兄弟小馬のチェスの駒は、チェスの駒のない位置を自然に通過できます。チェスの駒が目の前にある場合、シャオマ兄弟はそれを直接スキップできます。異なる色のチェスの駒が 2 つ以上つながっている場合、Xiaoma のチェスの駒はジャンプできません。このとき、飛び越えるにはエネルギーを消費してチェスの駒をいくつか破壊する必要があります。しかし、小馬兄弟のチェスの駒はアップグレードされており、同じ色の一連のチェスの駒が揃うと、小馬兄弟は直接スキップできます。チェスの駒を破壊するには、少しエネルギーを消費することが知られています。コードの弟が終点 (座標 n+1) に到達するには、少なくともどれくらいのエネルギーを費やす必要があるのでしょうか?

フォーマット

入力形式:
行 1 には正の整数 n が含まれ
、行 2 にはチェス盤の状態を示す n 個の整数 ai (1<=i<=n) が含まれます. 出力形式
:
消費されるエネルギーの最小量を出力する整数

サンプル1

入力:
5
0 1 1 0 0.
出力
: 0

述べる:

3<=n<=10 の 5 回

(2) 参照コード

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 7;
int a[N];
int main()
{
    
    
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
    
    
        cin >> a[i];
    }
    int ans = 0;
    for (int i = 1; i <= n; i++) {
    
    
        if (a[i] && a[i - 1] && a[i] != a[i - 1]) {
    
    
            a[i] = 0;
            ans++;
        }
    }
    cout << ans << endl;
    return 0;
}


23. MT2123 兄弟小馬の編成命令

(1) タイトルの説明:
小馬兄弟は x 軸と見なすことができる道路上に n 個の部隊を配置しており、小馬兄弟の指揮は原点にあり、第 i 軍は α[ 連隊の位置にあります。 ] 、ここで軍隊の位置を再配置します。配置後の位置を b[連隊] とし、b[連隊] ≥ a[列] を要求し、各ユニット間の距離は X 以上です。

部隊は最初の部隊から移動を開始するので、現状(自分の前の通し番号の部隊が更新された状況を指す)、つまり部隊ごとに最適解を作る必要があります。上記の条件が満たされている場合、軍隊が兄弟シャオマに近いほど良い.

フォーマット

入力形式:
1 行目に 2 つの整数 n, ac;
2 行目に a[i] を表す n 個の整数; .出力形式
: 1 行、スペースで区切られた b[i] を出力

サンプル1

入力:
4 11
1 21 11 7.
出力
: 1 21 32 43

述べる:

ヒント: 1≤n≤1000、1≤a、a[i]、b[i]≤106 回

(2) 参照コード

#include<bits/stdc++.h> 

using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define rall(a) a.rbegin(), a.rend()
#define fi first
#define se second
#define rep(i,s,n) for(int i=s;i<n;i++)
#define repd(i,s,n) for(int i=s;i>=n;i--)
const int MOD=1e9+7;
const int maxN=5e3+1;
 const int INF=2e9;
 const int MB=20;
 const int MAX_LEN=200001;
 ull s[MAX_LEN];
 ull p[MAX_LEN];
 void solve()
 {
    
    
 ll n,x;
 cin>>n>>x;
 rep(i,0,n)
 {
    
    
 cin>>s[i];
 p[i]=s[i];
 }
 ll pre=s[0];
 rep(i,1,n)
 {
    
    
 sort(p,p+i);
 ll temp;
 rep(j,0,i)
 {
    
    
 temp=p[j]+x;
 if (j==i-1)
 break;
 else
 {
    
    
 if (p[j+1]-temp>=x)
 break;
 }
 } 
 s[i]=temp>s[i]?temp:s[i];
 p[i]=s[i];
 }
 rep(i,0,n)
 cout<<s[i]<<" " ;
 }
 int main()
 {
    
    

 solve();
 return 0;
 }


24. MT2124 アクティビティのグループ化

(1) タイトルの説明
Xiaoma 兄弟はチーム ビルディング活動を組織しており、合計 n 人が参加しています。活動はAとBの2つのプロジェクトに分かれており、各プロジェクトには2名がチームに参加する必要があります。各人がそれぞれAとBの習熟度を表す2つの能力値aとbを持っていると仮定します.活動を円滑に進めるために、Xiaoma兄弟は、それぞれの2人のA能力値の合計がグループは B の能力値の合計に等しくなります。シャオマ兄弟の考えを満たすためにグループ化の可能性があるかどうかを計算するのを手伝ってください。

フォーマット

入力形式
合計3行入力、1行目の偶数n∈[2,1×10]は総人数、2行目のn正整数は各人のプロジェクトAの能力値、3 行目の n 個の正の整数は、各人の B アイテムの能力値を示します。
・出力
形式:1行、グループがあれば出力可、それ以外は出力不可

サンプル1

入力:
6
1 2 3 4 5 6
6 5 4 3 2 1.
出力
:はい

述べる:

第1組と第6組、第2組と第5組、第3組と第4組、それぞれの組のアイテムAの能力値の合計は7、アイテムBの能力値の合計はいずれも7です。

(2) 参照コード

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
pii p[100005];
multiset<pii> s;
int main() {
    
    
    int n;
    ll suma = 0, sumb = 0;
    cin >> n;
    int m = n / 2;
    for (int i = 1; i <= n; ++i) {
    
    
        cin >> p[i].first;
        suma += p[i].first;
    }
    for (int i = 1; i <= n; ++i) {
    
    
        cin >> p[i].second;
        sumb += p[i].second;
    }
    if (suma % m != 0 || sumb % m != 0) {
    
    
        cout << "NO" << endl;
        return 0;
    }
    suma /= m, sumb /= m;
    for (int i = 1; i <= n; ++i) {
    
    
        s.insert(p[i]);
    }
    for (int i = 1; i <= n; ++i) {
    
    
        if (s.empty()) break;
        if (s.find(p[i]) == s.end())
            continue;
        auto it = s.find(p[i]);
        s.erase(it);
        pii q = {
    
    suma - p[i].first, sumb - p[i].second};
        if (s.find(q) == s.end()) {
    
    
            cout << "NO" << endl;
            return 0;
        }
        it = s.find(q);
        s.erase(it);
    }
    cout << "YES" << endl;
}

25. MT2125 フードデリバリー

(1) タイトルの説明
小猫は再びフード デリバリー ステーションの建設を任されました.すべての居住者の居住場所 α は同じ x 軸上にあります. 小猫はフード デリバリーの移動距離を最短にするために、フードデリバリーステーション. . 駅から各居住者までの距離の合計が最小になるように駅を建設する場所を見つけます。

注: 居住者の居住地 a が一意であるとは限りません。つまり、2 人の居住者が同じ居住地を持っている可能性があり、テイクアウト ステーションが居住地にあることは許可されます。

フォーマット

入力形式:1行目に整数N、2行目にN個の整数A~AN。
・出力
形式:距離の和の最小値を表す整数を出力します。

サンプル1

入力:
4
6 2 9 1.
出力
: 12

述べる:

ヒント: 100% データの場合: 1<N ≤100000、abs(ai)≤10000000

(2) 参照コード

#include<bits/stdc++.h> 

using namespace std;

int n1[100005],n2[100005];
int main(){
    
    
int n;
long long sum=0;
cin>>n;
for(int i=0;i<n;i++)
cin>>n1[i];
sort(n1,n1+n);
for(int i=n-1;i>=0;i--){
    
    
n2[n-1-i]=n1[i];}
for(int i=0;n1[i]<n2[i];i++)
sum+=n2[i]-n1[i];
cout<<sum<<endl;
return 0;
}


エピローグ

コード問題集問題バンクの上級塔350問題は順次更新しており、Xingyao、Kingの質問を順次フォローアップしていきますので、どうぞお楽しみに!! !
同時に、これらの質問がすべての人を助け、一緒に進歩することを願っています. アルゴリズムの道のすべての「修行僧」が困難を乗り越え、最終的に肯定的な結果を達成できることを願っています. 私はこの道を選んだので、私はここに来て、途中で諦めてしまって、可哀想すぎませんか?

中国コンピュータ連盟の優秀なメンバーであり事務局長であるXuan Ge 博士のステーション B のビデオ説明リンクを添付します( ̄▽ ̄~)~

あなたの結末が、途中の浮き沈みに値するものでありますように。

おすすめ

転載: blog.csdn.net/m0_54754302/article/details/128277693