西瓜の備忘録

競プロとかで気づいたこととか考察を書き留めるためのブログ

ABCかと思ったらARCだった(ARC080)

タイトル通り

何を言ってるのか わからねーと思うが

ABC参加しようと思ってARC参加ボタン押してました

初めて1時間でD問まで解けたのに悲しい

 

以下自分のガバガバ解答

C

長さNの数列与えられて隣り合う2数の積が4の倍数になるように並び替えできるかという問題

2数の積が4の倍数になるとき、片方が4の倍数または両方が2の倍数である必要があるから~みたいな感じで解いた 

main(){
int N,a;
int cnt[3] = {};//それぞれの倍数の数 x1,x2,x4
cin >> N;
for(int i = 0;i < N;i++){
cin >> a;
if(a % 4 == 0)cnt[2]++;
else if(a % 2 == 0)cnt[1]++;
else cnt[0]++;
}
if(cnt[0]){//x1が存在する
if(cnt[1])cnt[0]++;//2の倍数を一纏めに
if(cnt[0] <= cnt[2]+1) cout << "Yes" << endl;//4の倍数を交互に配置できる場合
else cout << "No" << endl;
}else{
cout << "Yes" << endl;
}
}

D

同じ数を隣接して表示しなさいって問題

yukicoderのNo.401 数字の渦巻き

みたいに渦巻き状に配置すれば必ず隣接するだろうと思って解いた

かなり汚いコードになってるからいずれ書き直す

(追記)解説読んでから気づいたけど渦巻き状にしなくても蛇状にすればいいっぽい

main(){
int H,W,N;
pair<int,int> p[10000];
cin >> H >> W >> N;
for(int i = 0;i < N;i++){
int a;
cin >> a;
p[i] = make_pair(a,i+1);
}
sort(p,p+N);
int next = p[0].second;//次の数
int r = p[0].first;//次の数の残り数
int muki = 0;//→↓←↑
int x = 0,y = 0;//座標
int num = 0;//次の配列のインデックス
int map[100][101];
for(int i = 0;i < H;i++){
for(int j = 0;j < W;j++){
map[i][j] = -1;//初期化
}
}
for(int i = 0;i < H*W;i++){
if(x < 0 || x >= W || y < 0 || y >= H ||
map[y][x] != -1){
if(muki == 0){x--;y++;}
if(muki == 1){y--;x--;}
if(muki == 2){x++;y--;}
if(muki == 3){y++;x++;}
muki = (muki + 1) % 4;
}
if(!r){
r = p[++num].first;
next = p[num].second;
}
map[y][x] = next;
r--;
if(muki == 0)x++;
if(muki == 1)y++;
if(muki == 2)x--;
if(muki == 3)y--;
}
for(int i = 0;i < H;i++){
for(int j = 0;j < W;j++){
printf("%d%c",map[i][j],j==W-1?'\n':' ');
}
}
}