前言
重回程式設計第一天…
因為種種原因停更好久,直到最近,我決定重新開始寫題目。這次的題目選自 https://codeforces.com/contest/1790 ,剛回來想用 Div3 試個手感,沒想到也卡了許久。
本文
言歸正傳,本質上這還是一個分享網站。那我今天用了三個小時總共寫出5題(共7題)。以下是提示、想法、與程式碼的分享。
pA Polycarp and the Day of Pi
簡單說就是求前30位的圓周率他寫對幾位,比較需要注意的是範例已經給一個完整的圓周率。
#include<bits/stdc++.h>
using namespace std;
// a 是輸入
string ans="314159265358979323846264338327",a;
void solve(){
cin>>a;
int same=0;
// 逐位判斷
for(int i=0;i<a.size();++i){
if(a[i]==ans[i]){
same++;
}else{
break;
}
}
cout<<same<<"\n";
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
int t;
cin>>t;
while(t--){
solve();
}
}
pB Taisia and Dice
題目概要
給你三個數字 ,n是骰子數,s是點數總和,r則是扣掉一個最大的骰子點數後的點數總和。求一個可能的點數序列。
提示1
最大的點數是s-r
提示2
這序列沒有規定骰子點數不能重複
想法
綜合兩個提示,我們可以發現。盡量先用最大點數(s-r),最後都用1點,中間再補差額就可以了。程式碼的表達正好相反。
程式碼
#include<bits/stdc++.h>
using namespace std;
void solve(){
int n,s,r;
cin>>n>>s>>r;
int d=s-r,sum=0;
for(int i=1;i<=n;++i){
// n-i+1 = 剩餘骰子數
if(n-i+1==s-sum){
cout<<1<<" ";
sum++;
}else if(n-i<s-sum && s-sum-d<n-i){
cout<<s-sum-(n-i)<<" ";
sum+=s-sum-(n-i);
}else{
cout<<d<<" ";
sum+=d;
}
}
cout<<"\n";
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
int t;
cin>>t;
while(t--){
solve();
}
}
pC
題目概述
有一個1-n都出現過一次的序列讓你猜,然後不按順序的給你n個數列,每個數列都是原本的序列但會刪除一個元素。求原序列。
例如:
3
2 3
1 3
1 2
則原序列為1 2 3。
提示1
只需要兩個序列就可以求出完整的。
提示2
頭尾的元素是關鍵。
想法
其實找到兩個關鍵序列就可以了,就是刪掉第一個和刪掉最後一個的。
例如:
4 2 1
4 2 3
2 1 3
4 1 3
就只需要
4 2 1
2 1 3
就可以還原整個序列。
那至於如何尋找,如提示2所述,關注第一個與最後一個元素。不同的那個就是我們要的。
程式碼
#include<bits/stdc++.h>
using namespace std;
// s[i] 序列的第一個數字為i的次數
// sr[i] 最後一個
// bd[i][j] 存讀進來的資料
// f 第一個元素,r則是最後一個
// d,c就是我們要找的那兩個序列
int bd[105][105],s[105],sr[105],f,d,r,c;
void solve(){
int n;
cin>>n;
for(int i=1;i<=n;++i){
for(int j=1;j<n;++j){
cin>>bd[i][j];
}
}
// 初始化
f=-1;
r=-1;
for(int i=1;i<=n;++i){
s[i]=0;
sr[i]=0;
}
// 找f,r
for(int i=1;i<=n;++i){
s[bd[i][1]]++;
sr[bd[i][n-1]]++;
if(s[bd[i][1]]>1){
f=bd[i][1];
}
if(sr[bd[i][n-1]]>1){
r=bd[i][n-1];
}
}
// 找不同於f,r的
for(int i=1;i<=n;++i){
if(bd[i][1]!=f){
d=i;
}
if(bd[i][n-1]!=r){
c=i;
}
}
for(int i=1;i<=n-1;++i){
cout<<bd[c][i]<<" ";
}
cout<<bd[d][n-1];
cout<<"\n";
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
int t;
cin>>t;
while(t--){
solve();
}
}
pD Matryoshkas
題目概述
給你一堆俄羅斯娃娃的大小,問你原來最少有幾組。其中,每一組的娃娃大小都必須要是連續整數。例如1 2 3。
提示1
能疊越多層越好。
提示2
動態的資料增刪操作。
想法
能疊越多層越好,因此,每一次都用while嘗試往上疊。那就需要尋找一個大小+1的娃娃存不存在。可以使用multiset或是map,而我選map。
程式碼
#include<bits/stdc++.h>
using namespace std;
void solve(){
int n,a,sum=0;
cin>>n;
map<int,int> mp;
for(int i=0;i<n;++i){
cin>>a;
mp[a]++;
}
for(auto e:mp){
while(e.second>0){
int tp=e.first;
while(mp.count(tp+1) && mp[tp+1]>0){
mp[tp+1]--;
tp++;
}
sum++;
e.second--;
}
}
cout<<sum;
cout<<"\n";
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
int t;
cin>>t;
while(t--){
solve();
}
}
pE Vlad and a Pair of Numbers
題目概述
給你一個x,找到a,b滿足 ,其中
是xor,也就是C++上的
a^b;
第五題最後有偷看詳解,使用的做法請見-> https://codeforces.com/blog/entry/111948