第1回アルゴリズム検定
A - 2倍チェック
各文字数字であるかをチェックする.数字以外が一つでもあったらエラー.
int main() {
string S;cin>>S;
bool error=false;
for(int i=0;i<3;i++){
if(S[i]<'0'||'9'<S[i])error=true;
}
if(error){
cout<<"error"<<endl;
}else{
cout<<stoi(S)*2<<endl;
}
}
B - 増減管理
問題文の通りに実装するだけ.
int main(void){
int N;cin>>N;
vector<int>A(N);
rep(i,N)cin>>A[i];
rep(i,N-1){
int d=abs(A[i]-A[i+1]);
if(A[i]==A[i+1])cout<<"stay"<<endl;
if(A[i]<A[i+1])cout<<"up "<<d<<endl;
if(A[i]>A[i+1])cout<<"down "<<d<<endl;
}
}
C - 3番目
ソートすれば楽.
int main(void){
vector<int> A(6);
rep(i,6)cin>>A[i];
sort(all(A));
cout<<A[3]<<endl;
}
D - 重複検査
添字に注意して実装する.
int main(void){
int N;cin>>N;
vector<int> A(N+1,0);
bool c=true;
int d=0;
rep(i,N){
int a;cin>>a;
A[a]++;
if(A[a]==2){
d=a;
c=false;
}
}
int n=0;
rep(i,N)if(A[i+1]==0)n=i+1;
if(c){
cout<<"Correct"<<endl;
}else{
cout<<d<<" "<<n<<endl;
}
}
E - SNSのログ
問題文の通りに丁寧に実装する. コードが汚い.
int main(void){
int N;cin>>N;
int Q;cin>>Q;
vector<vector<bool>> F(N,vector<bool>(N,false));
rep(i,Q){
vector<vector<bool>> F2(N,vector<bool>(N,false));
int t;cin>>t;
if(t==1){
int a,b;cin>>a>>b;
a--;b--;
F2[a][b]=true;
}else if(t==2){
int a;cin>>a;a--;
for(int k=0;k<N;k++){
if(F[k][a]){
F2[a][k]=true;
}
}
}else if(t==3){
int a;cin>>a;a--;
for(int k=0;k<N;k++){
if(F[a][k]){
for(int l=0;l<N;l++){
if(F[k][l]&&l!=a){
F2[a][l]=true;
}
}
}
}
}
for(int i=0;i<N;i++){
for(int k=0;k<N;k++){
F[i][k]=F[i][k]||F2[i][k];
}
}
}
for(int i=0;i<N;i++){
for(int k=0;k<N;k++){
cout<<(F[i][k]?"Y":"N");
}
cout<<endl;
}
}
F - DoubleCamelCase Sort
問題文の通りに実装する.
int main(void){
string S;cin>>S;
vector<pair<string,string>> T(0);
string tmp="";
tmp.push_back(S[0]);
for(int i=1;i<S.size();i++){
tmp.push_back(S[i]);
if('A'<=S[i]&&S[i]<='Z'){
string tmp2="";
for(char&c:tmp){
if('A'<=c&&c<='Z')tmp2.push_back(c-'A'+'a');
else tmp2.push_back(c);
}
T.push_back({tmp2,tmp});
i++;
tmp="";
tmp.push_back(S[i]);
}
}
sort(all(T));
for(auto&t:T)cout<<t.second;
cout<<endl;
}
G - 組分け
$3^10$があまり大きくないので,$3^10$通り全探索する.答えがマイナスになるパターンがあるので注意.
vector<vector<int>> permutation(int N,int U,bool h=false){
//0,1,2,3,...,N-1のN個からU個選ぶ順列
vector<vector<int>> A(0);
auto fun = [&h,&A,&N,&U](auto &fun,vector<int> &B)->void{
if((int)B.size()==U){
auto C=B;
do{
A.push_back(C);
}while(next_permutation(C.begin(),C.end()));
return;
}
int s = (h?0:-1);
if(!B.empty())s = B.back();
for(int x=s+(h?0:1);x<N;x++){
B.push_back(x);
fun(fun,B);
B.pop_back();
}
};
vector<int> C={};
fun(fun,C);
return A;
}
int main(void){
int N;cin>>N;
vector<vector<long>> A(N,vector<long>(N));
for(int b=0;b<N;b++){
for(int a=b+1;a<N;a++){
cin>>A[a][b];
}
}
auto B = permutation(3,N,true);
long ans = -INFl;
for(auto &C:B){
long s = 0;
for(int b=0;b<N;b++){
for(int a=b+1;a<N;a++){
if(C[a]==C[b]){
s += A[a][b];
}
}
}
chmax(ans,s);
}
cout<<ans<<endl;
}
H - まとめ売り
全種類販売をするとき,1番カードの残りが少ないものよりも$a$が大きければ販売することができる. そうでなければ販売できない.よって,常に1番カードの残りが少ないものを記録しておけば良い.
int main(void){
long N;cin>>N;
vector<long>C(N);cin>>C;
int Q;cin>>Q;
long cnt = 0;
long odd = 0,sum = 0;
long minOdd = INFl,minEven = INFl;
rep(i,N){
if(i%2==1){//偶数
chmin(minEven,C[i]);
}else{
chmin(minOdd,C[i]);
}
}
rep(i,Q){
int t;cin>>t;
if(t==1){
long x,a;cin>>x>>a;
x--;
if(x%2==0){//奇数
if(C[x]-odd-sum-a>=0){
C[x]-=a;
cnt+=a;
chmin(minOdd,C[x]);
}
}else{
if(C[x]-sum-a>=0){
C[x]-=a;
cnt+=a;
chmin(minEven,C[x]);
}
}
}else if(t==2){
long a;cin>>a;
if(minOdd-odd-sum-a>=0){
odd+=a;
cnt+=a*((N+1)/2);
}
}else if(t==3){
long a;cin>>a;
if(minOdd-odd-sum-a>=0 && minEven-sum-a>=0){
sum+=a;
cnt+=a*N;
}
}
}
cout<<cnt<<endl;
}
I - 部品調達
bitDPの問題.
int main(void){
int N,M;cin>>N>>M;
vector<int> S(M,0);
vector<long> C(M);
rep(i,M){
string s;cin>>s;
for(auto&c:s){
S[i]<<=1;
S[i]|=(c=='Y');
}
cin>>C[i];
}
vector<vector<long>> dp(M+1,vector<long>(1<<N,INFl));
//dp[a][b] := a番目まで集合bを得るコストの最小値
dp[0][0] = 0;
for(int a=0;a<M;a++){
for(int b=0;b<(1<<N);b++){
chmin(dp[a+1][b],dp[a][b]);
chmin(dp[a+1][b|S[a]],dp[a][b]+C[a]);
}
}
auto ans = dp[M][(1<<N)-1];
if(ans==INFl)ans=-1;
cout<<ans<<endl;
}
J - 地ならし
一見面倒な探索問題だが,$O((HW)^3)$でも間に合うことに甘えて愚直実装をする.
int main(void){
int H,W;cin>>H>>W;
vector<vector<long>>A(H+2,vector<long>(W+2,INFl));
rep(i,H){
rep(j,W){
cin>>A[i+1][j+1];
}
}
vector<vector<long>> BL(H+2,vector<long>(W+2,INFl));
vector<vector<long>> BR(H+2,vector<long>(W+2,INFl));
vector<vector<long>> UR(H+2,vector<long>(W+2,INFl));
vector<int> dy={1,-1,0,0};
vector<int> dx={0,0,1,-1};
BL[H][1]=BR[H][W]=UR[1][W]=0;
rep(_,H*W){
rep1(i,H){
rep1(j,W){
rep(k,4){
chmin(BL[i][j],BL[i+dy[k]][j+dx[k]]+A[i][j]);
chmin(BR[i][j],BR[i+dy[k]][j+dx[k]]+A[i][j]);
chmin(UR[i][j],UR[i+dy[k]][j+dx[k]]+A[i][j]);
}
}
}
}
long ans = INFl;
rep1(i,H){
rep1(j,W){
chmin(ans,BL[i][j]+BR[i][j]+UR[i][j]-2*A[i][j]);
}
}
cout<<ans<<endl;
}