タイトル:ブルーブリッジ2020年3月カップレースシミュレーションの問題解決のレポートで
カテゴリ:
- ACM
- レポートの問題解決の
タグ: - ブルーブリッジシミュレーションカップ2020大会の
日時:2020年3月26日午前10時33分02秒
概要
第1変換部タイトル
タイトル
[問題の説明]
コンピュータストアでは、15.125ギガバイトはどのくらいMB?
[回答]提出
これは空白の質問で塗りの結果であり、あなただけの計算結果を提出する必要があります。この質問の結果は整数、整数でのみ塗りつぶしへの回答を提出する際に、余分なコンテンツで塗りつぶしが得点しませんです。
思考
1G = 1024M
答え
15488
数の数について2番目の質問
タイトル
[問題の説明]
どのように多くの(唯一の正の数について計算して)120万程度の数。
[回答]提出
これは空白の質問で塗りの結果であり、あなただけの計算結果を提出する必要があります。この質問の結果は整数、整数でのみ塗りつぶしへの回答を提出する際に、余分なコンテンツで塗りつぶしが得点しませんです。
思考
+列挙をチェック
参照コード
#include<cstdio>
#include<memory>
#include<cmath>
#include<cstring>
#include<iostream>
using namespace std;
int main()
{
//freopen("input2.txt","r",stdin);
int i=1200000,sum=0;
for(int j=1;j<=i;j++)
{
if(i%j==0)
sum++;
}
cout<<sum;
return 0;
}
答え
96
3番目の質問リーフノード番号
タイトル
[問題の説明]
2019年は、バイナリツリーノードが含まれている、葉ノードの数がアップ含ん?
[回答]提出
これは空白の質問で塗りの結果であり、あなただけの計算結果を提出する必要があります。この質問の結果は整数、整数でのみ塗りつぶしへの回答を提出する際に、余分なコンテンツで塗りつぶしが得点しませんです。
思考
NIは、ノードI、3つだけのバイナリツリーノード、三種類0,1,2度の程度です。そして、次のような関係を持っています
N = N0 + N1 + N2
N0 = N2 + 1
**方法1証明:n個のノードN1側の**総二分木、N1 = 2 * N2 + N1、式1に得るために:N0 = N2 + 1
**証明方法2:** N0を組み合わせ還元リーフノードを介して各2つのリーフノード一度言うことであるリーフノードの数、最初の合併N2を介して2つのリーフノードの各々、新たなリーフノードを取得し、ありますN2を生成します。組み合わされ、N-1、N-1 N2ルートノードのので、N0 = N2 + 1を生成する必要があります
リーフノード(N0)を補うために、n1は0に設定され、最小化されなければならず、N0 = N2 + 1、得ることがN2 =(2019から1)/ = 1009 2ためN0 = 1010
答え
1010
第四に質問番号9
タイトル
[問題の説明]
2019から1、数9であっ桁どのように多くの数?
数字のいくつかの数が9個以上が含まれていることを注意、この数は一度だけカウントされます。計算はほんの数演算子である場合、例えば、数1999、数9を含んでいます。
[回答]提出
これは空白の質問で塗りの結果であり、あなただけの計算結果を提出する必要があります。この質問の結果は整数、整数でのみ塗りつぶしへの回答を提出する際に、余分なコンテンツで塗りつぶしが得点しませんです。
思考
二つの方法
(1)デジタルと決意の各ビットに基づいて計算しました。
(2)文字列
擬似コード
for i from 9 to 2019
if str(i).contains('9')
ans++
リファレンスコード:
#include<cstdio>
#include<memory>
#include<time.h>
#include<cstring>
#include<iostream>
using namespace std;
bool check(int i) {
char s[5];
sprintf(s, "%d", i);
string str(s);
return str.find('9') != string::npos;
}
int main()
{
//freopen("input2.txt","r",stdin);
int n=2019,sum=0;
int a=clock();
for(int j=1;j<=n;j++)
{
int g=j%10;
int s=(j/10)%10;
int b=(j/100)%10;
int q=(j/1000)%10;
if(g==9||s==9||b==9||q==9)
sum++;
//cout<<q<<b<<s<<g<<endl;
}
cout<<sum<<" 用时:"<<clock()-a<<endl;
a=clock();
sum=0;char s[10];
for (int i = 1; i <= n; ++i) {
sprintf(s,"%d",i);
string str(s);;
if(str.find('9')!=string::npos)
sum++;
}
cout << sum <<" 用时:"<<clock()-a<<endl;
return 0;
}
答え
544
桁数を増やすの第五の質問
タイトル
[問題の説明]
正の整数数字でない場合より右に隣接するいずれかの数字が数1桁増加と呼ばれるよりも、例えば、1135はデジタル増分数ではなく、1024桁の数がインクリメントされます。
正の整数nを考えると、我々は1からnまでの整数の数を増やすにはどのように多くの桁数をだろうか?
[入力形式]
入力整数nの最初の行を含みます。
[出力形式]
出力ラインは答えを表す整数が含まれています。
[サンプル入力】
30
[サンプル出力]
26
[評価]実施例及びスケールの表記
例中40%による評価のために、1 <= N <= 1000 。
実施例中80%による評価のために、1 <= N <= 100000 。
評価のためのすべてのユースケース、1 <= N <= 1000000 。
アイデアO(kNの)
二つの方法
(1)それぞれについて計算、それが決定されます
(2)1〜nは反復
文字列に
すべての反復ストリング、要件を満たすためにかどうかを決定します
参照コード
#include<cstdio>
#include<memory>
#include<time.h>
#include<string.h>
#include<iostream>
using namespace std;
int main()
{
//freopen("input2.txt","r",stdin);
int n,sum=0;
cin>>n;
int c=clock();
for(int i=1;i<=n;i++)
{
int t=i,lwei=10,j;
for(j=1;j<=7;j++)
{
int wei=t%10;
t/=10;
if(wei>lwei)
break;
lwei=wei;
}
if(j>7)
sum++;
}
cout<<sum<<" 用时:"<<clock()-c<<endl;
sum=0;
c=clock();
char a[7];
for(int i=1;i<=n;i++)
{
int j;
sprintf(a,"%d",i);
for(j=1;j<strlen(a);j++)
if(a[j-1]>a[j])
break;
if(j==strlen(a))
sum++;
}
cout<<sum<<" 用时:"<<clock()-c<<endl;
return 0;
}
質問6つのインクリメントトリプル
タイトル
[問題の説明]
列の数[1]、[2 ]、...、[n]は、添え字I、J、Kは0 <I <J <K <用の場合 、N + 1 及び[I] <[J ] <[I]、[Jと呼ばれる[K]、 ]、[K]はトリプルの集合だけインクリメントされ、[j]は、中心トリプルをインクリメントします。
中央のトリプルをインクリメントすることができますどのように多くの要素を依頼する列の数、列番号を与えられました。
[入力形式]
入力整数nの最初の行を含みます。
二行目に含まれるn個の整数[1]、[2 ]、...、[n]は、 列の所定の数を表し、隣接する整数の間の空間によって分離されました。
[出力形式]
出力ラインは答えを表す整数が含まれています。
[サンプル入力】
5
1 2 3 5 5
[サンプル出力]
2
[サンプル記述]
[2]と[4]はトライアドの中心であってもよいです。
[評価]例の規模とで合意
実施例中50%による評価のため、2 <= N <= 100,0 <= <= 1000の列数。
評価のためのすべてのユースケース、2 <= N <= 1000,0 << = = 10000の列数。
思考のO(N ^ 2)
列挙の各要素
前の要素に比べて素子の、小さな見つける
バック要素と比較要素のが、大見つけることができる
上記の二つが真である、すなわち、現在の要素は、中央トリプレットとして記述することができる
(O N ^ 2)、戦いが1秒以内に解決することができるように1000 Nの最大ため。
参照コード
#include<cstdio>
#include<memory>
#include<time.h>
#include<cstring>
#include<iostream>
using namespace std;
int main()
{
//freopen("input.txt","r",stdin);
int n,sum=0,a[10000],j,k;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
int c=clock();
for(int i=1;i<=n-2;i++)
{
for(j=0;j<i;j++)
{
if(a[j]<a[i])
break;
}
if(j==i) continue;
for(k=i+1;k<n;k++)
{
if(a[i]<a[k])
break;
}
if(k==n)
continue;
sum++;
}
cout<<sum<<" 用时:"<<clock()-c;
return 0;
}
Q7音節判決
タイトル
[問題の説明]
非常にちょうどそのような単語に興味その単語ハローと同様ボブは、4つのセクション、一つ以上の文字の子音によって最初のセクション、一つ以上の文字の母音第二セグメント、第3のセグメントに分割することができます1つの文字以上の子音、一個の以上の文字の母音第四項によります。
それ以外の場合は出力なし、あなたの出力がYESであれば言葉は、そのようなAの単語であるかどうかを判断するために、言葉を与えられていません。
母音、E、など私は、O、 U、 5の合計は、他の子音です。
[入力形式]
単語を含む行を入力し、単語は小文字のみが含まれています。
[出力形式]
出力、またはそうに答え、または全くありません。
[サンプル入力】
lanqiao
[サンプル出力]
はい
[サンプル入力】
世界
[サンプル出力]
番号
[評価]例の規模とで合意
評価のすべてのケースでは、単語の文字の数が100を超えてはなりません。
思考
三つの方法
(1)それは子音セットY(BOOL)が0であれば母音が見つかるまで、標準を記録し、列を横切る横に進み、第二母音が見つかり、その後、最初のインデックスは母音ではないかを決定第二子音と母音がされた後0、それが非ゼロでなければなりません
(2)論理和:トラバーサル文字列は、計算(judge(s[i])+judge(s[i+1]))==1
の最後の数== 3は、物質を例示することを意図している場合は、回数を
(3)メソッドの文字列準備
最初の母音のインデックスindex1のを見つけ、0より大きくなければなりません、と見つけることができる
見つけることができなければならない、index1ののINDEX2に沿って非母音GETを見つけるために、継続して次
を見つけることができなければなりません、INDEX2に沿って次の母音index3の取得を見つけるために続け
、最後にindex3-1(index3と後続の文字が母音でなければならないので)最初の非母音でなければならないバックからの文字の位置を決定します
参照コード
//qwrtypsdfghjklzxcvbnmaeiouuoieamnbvcxzlkjhgfdspytrwqaaeeiioouu
//yes time=0
//yes time=0
//yes time=0
#include<cstdio>
#include<memory>
#include<time.h>
#include<cstring>
#include<iostream>
using namespace std;
bool judge(char c)
{
if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u')
return 1;
return 0;
}
int main()
{
//freopen("input.txt","r",stdin);
string s;
int index[2];
int in=0,sum=0,k;
bool y=0,flag=0;
cin>>s;
int c=clock();
for(int i=0;i<s.length();i++)
{
if(judge(s[i]))
{
if(y==0)
{
y=1;
index[in++]=i;
if(in==2)
{
if(index[0]==0)
{
flag=0;
break;
}
for(k=index[1];k<s.length();k++)
{
if(!judge(s[k]))
{
flag=0;
break;
}
}
if(k==s.length())
flag=1;
else
break;
}
}
else
continue;
}
else
y=0;
}
if(flag) cout<<"yes";
else cout<<"no";
cout<<" time="<<clock()-c<<endl;
c=clock();
int jiao=0;
for(int i=0;i<s.length()-1;i++)
{
if((judge(s[i])+judge(s[i+1]))==1)
jiao++;
}
if(jiao==3) cout<<"yes";
else cout<<"no";
cout<<" time="<<clock()-c<<endl;
c=clock();
int index1=s.find_first_of("aeiou");
if(!index1||index1==string::npos)
{
cout<<"no";
return 0;
}
int index2=s.find_first_not_of("aeiou",index1+1);
if(index2==string::npos)
{
cout<<"no";
cout<<" time="<<clock()-c<<endl;
return 0;
}
int index3=s.find_first_of("aeiou",index2+1);
if(index3==string::npos)
{
cout<<"no";
cout<<" time="<<clock()-c<<endl;
return 0;
}
int index4=s.find_last_not_of("aeiou");
if(index4!=index3-1)
{
cout<<"no";
cout<<" time="<<clock()-c<<endl;
return 0;
}
cout<<"yes";
cout<<" time="<<clock()-c<<endl;
return 0;
}
Q8長い草
タイトル
[問題の説明]
土地を暁、彼が小さなn行m列、行ごとにこの空間を分割し、各列の長さは1です。
暁明は、それらのいくつかの小さなクリアを選んだ、植え草や他の小片は、オープンスペースのまま。
草は毎月、非常に速く成長し、草の小片が植えられた場合には草のいくつかは、出て成長する、それがアップ所有することになり、下、左、右の4つの小さなオープンスペースの拡張を、四つの小クリアそれは草の小片になります。
k個の数ヶ月後にオープンスペース上の草があるどのような場所、暁明を教えてください。
[入力形式]
入力の最初の行は二つの整数N、Mを含有します。
続いてN行は、m個の文字を含む各行は、オープンスペースは、文字の間にスペースが存在しない、初期状態を示しています。小数点場合は、手紙gの場合、草の種類を表し、オープンスペースとして表現されます。
次は、整数kを含んでいます。
[出力形式]
N本の出力線は、m個の文字を含む各行は、kは状態空間ヶ月を表します。文字gは、長い草を表す場合は小数点場合は、オープンスペースとして表現されます。
[サンプル入力】
4
.G ...
...
... ... G
...
2
[サンプル出力]
GGGG。
GGGG。
GGGGG
.ggg。
[評価]例の規模とで合意
、2 <= N、M <実施例中30%による評価のため = 20。
実施例中70%による評価のため、2 <= N、M < = 100。
評価のためのすべてのユースケース、2 <= N、M < = 1000,1 <= K <= 1000。
思考のO(N * M)
(1)はおそらく時間をDFS
(2)一般的なマルチエントリBFSは、基本的な問題は、テンプレートです。ほとんどの時間計算量O(N * M)の。
参照コード
#include<cstdio>
#include<time.h>
#include<memory>
#include<queue>
#include<cstring>
#include<iostream>
using namespace std;
struct Point{
int x,y,kk;
};
char map[1010][1010],save[1010][1010];
int m,n,k;
queue<Point> q;
int dir[4][2]={0,1,0,-1,1,0,-1,0};
void manyan(int x,int y)
{
for(int i=0;i<4;i++)
{
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(xx>=0&&xx<m&&yy>=0&&yy<n)
{
if(map[xx][yy]=='.')
map[xx][yy]='d';
}
}
}
void bfs(){
Point a,b;
while(!q.empty())
{
a=q.front();
if(a.kk==k)
return ;
q.pop();
for(int i=0;i<4;i++)
{
b.x=a.x+dir[i][0];
b.y=a.y+dir[i][1];
if(b.x>=0&&b.x<m&&b.y>=0&&b.y<n&&map[b.x][b.y]=='.')
{
b.kk=a.kk+1;
map[b.x][b.y]='g';
q.push(b);
}
}
}
}
void show(char map[1010][1010])
{
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
cout<<map[i][j];
}
cout<<endl;
}
}
int main()
{
//freopen("input.txt","r",stdin);
cin>>m>>n;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
cin>>map[i][j];
if(map[i][j]=='g')
q.push({i,j,0});
}
}
memcpy(save,map,sizeof(map));
cin>>k;
int c=clock();
bfs();
cout<<"time="<<clock()-c<<endl;
show(map);
memcpy(map,save,sizeof(map));
c=clock();
for(int i=0;i<k;i++)
{
for(int ii=0;ii<m;ii++)
{
for(int j=0;j<n;j++)
{
if(map[ii][j]=='g')
manyan(ii,j);
}
}
for(int ii=0;ii<m;ii++)
{
for(int j=0;j<n;j++)
{
if(map[ii][j]=='d')
map[ii][j]='g';
}
}
}
cout<<"time="<<clock()-c<<endl;
show(map);
return 0;
}
第九タイトルシーケンスカウント
タイトル
[問題の説明]
正の整数の配列暁明の数は、以下の条件を満足する、疑問。
- 最初のnは、です。
- ないより多くのn-秒以上;
- 初めから第三のは、差の絶対値は、最初の2つのそれぞれよりも小さいです。
計算は、与えられたn個のために、どのように多くのシーケンスの条件を満たしています。
[入力形式]
入力行は、整数nを含んでいます。
[出力形式]
答を表し出力アン整数。答えは大きいかもしれない、回答出力は万で割ってください。
[サンプル入力】
4
[サンプル出力]
7
[サンプル記述]
以下の条件を満足する配列である
。4. 1
。4. 1. 1
4 1 2
4 2
4 1 2
4 3。
4. 4。
[評価]例の規模とで合意
評価のユースケース20%、1 <= N <= 5 ;
評価のユースケースの50%のために、1 <= N <= 10 ;
評価のユースケースの80%のために、1 <= N <= 100 ;
全てのレビューはケースを使用するために、 1 <= N <= 1000。
アイデア:
ボイドDFS1(現在選択されている点、次回選択範囲)
ポジティブ思考、すべての時間はあなたがダウンして見て、0にバックアップしないように選択することができる場所に注意を払う、(残業の)終わりと見られ、直接再帰条件
(選択されたデータの選択された数の)INT DFS2
リバース思考、そして半ダース、ケース自体がAであるため、1に初期化
メモリ再帰(O(N ^ 3))及び第二の同一のパラメータ
最初から、そのように、二種類が繰り返されてもよいが見られるマトリックスプラスレコード
再帰の最適化
dfs4(i、j)は前の点を示すが、Iであり、点[1、j]は明らかdfs4(I、J)= dfs4(I、J-1)+ 1 + dfs4(J、これらの可能性の和であります、| IJ |)、**なぜプラス1?**良い質問を、1は、(i、jを(ではないバック))を表すので、これは状況です
コード
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <ctime>
#define PP(a,b) cout<<a<<"="<<b<<endl
#define P(a) cout<<a<<endl
#define print(a) cout<<#a<<"="<<a<<endl
#define _for(i,s,e) for(int i=s;i<=e;i++)
using namespace std;
int mem[1001][1001],sum;
void dfs1(int aa,int jue)
{
if(aa==0)
{
sum++;
return ;
}
dfs1(0,aa);
_for(i,1,jue-1)
{
int t=(aa>=i)?(aa-i):(i-aa);
dfs1(i,t);
}
}
int dfs2(int a,int b)
{
int t=(a>=b?(a-b):(b-a));
int ans=1;
_for(i,1,t-1)
ans+=dfs2(b,i);
return ans%10000;
}
int dfs3(int a,int b){
if(mem[a][b]) return mem[a][b];
int cha=a>=b?(a-b):(b-a);
int ans=1;
_for(i,1,cha-1)
ans+=dfs3(b,i);
ans%=10000;
mem[a][b]=ans;
return ans;
}
int dfs4(int a,int b)
{
if(b<=0) return 0;
if(mem[a][b]) return mem[a][b];
int t=(a>=b?(a-b):(b-a));
return mem[a][b]=(dfs4(a,b-1)+1+dfs4(b,t-1))%10000;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n;
cin>>n;
int c=clock();
sum=0;
_for(j,1,n)
dfs1(j,n-j);
P(sum%10000);
PP("time",clock()-c);
c=clock();
sum=0;
_for(i,1,n)
sum+=dfs2(n,i);
P(sum%10000);
PP("time",clock()-c);
c=clock();
sum=0;
_for(i,1,n)
sum+=dfs3(n,i);
P(sum%10000);
PP("time",clock()-c);
memset(mem,0,sizeof(mem));
c=clock();
P(dfs4(n,n));
PP("time",clock()-c);
return 0;
}
Q10パーティーちらし
タイトル
[問題の説明]
パーティーを整理する暁明は、n個のプログラムの合計を用意しました。そして、夕方の時間は限られている、彼は唯一のm個のプログラムのいずれかを選ぶことができます。
このプログラムは、暁を変更することができないため、所与の意図Nのオーダーです。
暁明は、彼が格好良い、この文脈であなたに2番目のプログラムを望んとして選択された第1のプログラムを期待している、観客は党の度合いが非常に大きく関係し、見た目の良い最初の数のショーを持って好きなことを見出した格好良い順に、ように。
各プログラムに暁明は、あなたが彼の要求を満たすため、暁明は、m個のプログラムを選択助け、nice値を定義します。
[入力形式]
入力の最初の行は二つの整数N、Mを含み、数は、選択される番組の数を表します。
二行目に含まれるnは整数、各プログラムのための魅力的な値に従いました。
[出力形式]
Mの出力ラインには、選択したプログラムの値を探して、整数を含みます。
[サンプル入力】
5 3
3 1 2 5 4
[サンプル出力]
3 5 4
[サンプル記述]
まず、4、5つのプログラムを選択します。
[評価]例の規模とで合意
評価のユースケースの30%を、1 <= N <= 20 ;
評価のユースケースの60%を、1 <= N <= 100 ;
全てのレビューはケースを使用するために、1 <= N <=魅力値100000,0 <=プログラム<= 100,000
了見違い
している間違った、二回あなたを注文することで解決した場合。値の合計は、選択した最大規模のプログラムであることを見ているが、見た目の良いしようとする前からされていませんので。すなわち、選択された順序の最大辞書の数M
思考
ST + RMQ
参照コード
#include<cstdio>
#include <algorithm>
#include<cmath>
#include<cstring>
#include<iostream>
#include<stdlib.h>
#define PP(a,b) cout<<a<<"="<<b<<endl
#define P(a) cout<<a<<endl
#define print(a) cout<<#a<<"="<<a<<endl
#define _for(i,s,e) for(int i=s;i<=e;i++)
using namespace std;
int n,m;
int a[100001];
int st[100001][20];
void cal(int a[],int n)
{
for(int j=1;(1<<(j-1))<=n;j++)
{
for(int i=0;i+(1<<j)-1<=n-1;i++)
{
st[i][j]=max(st[i][j-1],st[i+1<<(j-1)][j-1]);
}
}
}
int query(int s,int e)
{
int t=(int)(log(e-s+1)/log(2));
return max(st[s][t],st[e-(1<<t)+1][t]);
}
int main()
{
//freopen("input.txt","r",stdin);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
_for(i,0,n-1)
{
cin>>a[i];
st[i][0]=a[i];
}
cal(a,n);
int s=0,k=m;
while(k!=0)
{
int z=query(s,n-1-k+1);
cout<<z<<" ";
s=z+1;
k--;
}
}