首先是 廣告 (啓智樹官網)
誒,炸了就得自己承擔,吸取經驗下次不要再犯纔是最重要的(自我安慰。。。)
得知了有這場比賽,名肯定是要報的,但是真的有點不情願——這場比賽主要是小學生的,所以,對於我來說不拿第 ,第 顯然是說不過去。。。
但願不會出意外吧……
知道了規則,感覺挺意外的——還要開攝像頭和麥克風。當然,這是好事,不讓某某某這樣的同學誤入作弊的歧途
作業多多多,睡前都在做作業,怕不好明天考試還會去做作業(直播寫作業我怕不是要翻車,原形畢露了~
可惜出題人沒給我留下機會/kk
題目描述
2020年春節,新型冠狀病毒(後文簡稱新冠病毒)肆虐,居民必須佩戴口罩方能出門,一時之間口罩成爲緊缺物資,各地政府爲了避免出現哄搶現象,紛紛出臺各種措施,限制購買口罩的數量。淘淘所在社區就規定必須持身份證到指定藥房排隊購買一次性口罩,並且每戶每天只能派出一人購買,每次限購k(k>1)只。每次出門採購一次性口罩,將消耗家裏原有一次性口罩1只。由於藥房每天能夠供應的一次性口罩是有限的,並不能保證排隊的人都能買到,也就是說買到了就賺到k-1只,買不到就虧1只。已知淘淘家裏原有一次性口罩n只,出門若干次之後,家裏的一次性口罩變成了t只,請問淘淘至少出門了幾次?
做法&想法
做得挺順利,應該不大會翻車。
我們顯然有個貪心,顯然有一種策略——我們絕對不會先去賺 只,在去虧 只,因爲題目求的是最少出門次數。
代碼
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
int main(){
int n,t,k,ans=0;read(n);read(k);read(t);k--;
if(n>=t)return printf("%d\n",n-t),0;
int x=t-n;
if(x%k==0)ans+=x/k;
else ans+=x/k+1;
n+=ans*k;
ans+=n-t;
printf("%d\n",ans);
return 0;
}
題目描述
新冠病毒把每個人的生活節奏都打亂了,搞得大家都不能出門,更別提上幼兒園了,可把淘淘的小妹妹藍藍憋壞了,小傢伙在家老是纏着媽媽講故事,每當此時媽媽會講一些“從前有座山,山裏有座廟,廟裏有個老和尚給小和尚講故事,講的什麼呢?從前有座山……”這樣循環的故事,一直講到藍藍睡着或不想聽爲止。元宵節過後媽媽要上班了,爲了滿足藍藍聽媽媽講故事的需求,媽媽要淘淘把她講的故事錄音後用復讀機循環播放給藍藍聽,淘淘覺得整個故事有點長,全錄下來沒有必要,如果一個故事本身是週期性的,那麼只要找出它的最小週期,將開頭一段長度等於最小週期的內容錄下來用復讀機循環播放就行了。如故事內容爲“abcabcabcabc”,它的最小週期長度爲3,內容爲“abc”,只需將“abc”錄下來循環播放就行了。淘淘很忙,他把這個任務交給了你,要求寫一個程序,找出一個字符串的最小週期的長度。
做法&想法
我們可以枚舉答案,然後 判斷(最壞情況)
顯然是個枚舉的方法,感覺跑不滿,應該還行吧。
中間題目改了!差評!!!
由於之前的輸入格式沒有字符個數 ,所以我是直接
scanf("%s",ch);
n=strlen(ch);
結果,讀入 後,我的代碼就變成了
read(n);
for(int i=1;i<=n;i++)cin>>ch[i];
可以注意到,最開始是從 開始編號的寫法,後一種是從 開始編號的寫法,結果我以爲沒問題,改了之後樣例都不測就交了(這個行爲可以說是愚蠢至極!哎~)
代碼
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
char ch[100010];
int n;
bool check(int x){
for(register int i=x;i<n;i++)
if(ch[i]!=ch[i%x])return false;
return true;
}
int main(){
read(n);scanf("%s",ch);
for(register int i=1;i<n;i++)
if(check(i)){
printf("%d\n",i);
return 0;
}
cout<<n;
return 0;
}
題目描述
處理完復讀機的事,淘淘正想放鬆一下,口袋裏的手機響了,接通後傳來了青少年科技中心可人老師的親切聲音,可人老師要求淘淘出一道既能測出選手智力同時又不超出小學數學知識範圍的題,這讓淘淘犯難了,出什麼好呢?淘淘在腦海中將歷年的NOIP複賽題想了一遍,突然靈機一動,想到了Hankson的趣味題,淘淘覺得可以將它簡化改編一下,變成一道考驗小學生的智力問題,改編後的問題如下:給你兩個正整數X和Z,其中Z一定是X的倍數,要你求出滿足下列兩個條件的正整數Y
- 條件1:Z是X和Y的最小公倍數
- 條件2:在滿足條件1的前提下要求Y最小
淘淘考慮到小朋友們能來參加本次比賽都不容易,每個人都是各區的精銳之師,因此他在設計測試數據時手下留情了,使得每個小朋友都有大把的分數可拿,當然了,越是聰明的小朋友能拿的分越多!
做法&想法
PS:這題折騰了半個多小時,有難度的。
首先,我們將 、 和 用數論的形式表示一下。
那麼, 就等於
其中, 函數的定義如下:
當 中, 時, 爲 ;反之 時, 爲 。
因爲我們要 儘量小,所以,當 時,我們需要讓
所以, 就等於
其中, 函數的定義如下:
當 中, 時, 爲 ;反之 時, 爲 。
我們考慮實際意義,上述式子 就是 比 多的因子。
舉個例子:
所以
當然, 並不一定 ,所以,我們要用 來搞。
代碼
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
ll gcd(ll x,ll y){
if(x%y==0)return y;
return gcd(y,x%y);
}
int main(){
ll x,y,z;read(x);read(z);
y=z/x;
while(gcd(x,y)!=1){
int a=gcd(x,y);
y*=a;x/=a;
}cout<<y;
return 0;
}
題目描述
2022世界盃馬上就要開始了,經過一番激烈角逐,全球32支球隊獲得了出線資格。世界盃的比賽分爲兩個階段,分別爲小組賽階段和淘汰賽階段,在小組賽階段32支球隊將分成8個小組,每個小組4支球隊進行循環比賽,即每兩支球隊比賽一次,每支球隊會進行3場比賽,勝得3分,平得1分,輸得0分。陶陶和藍藍都是足球迷,藍藍預測了幾次2022世界盃小組賽各個隊伍的得分,陶陶想知道這些得分情況是否可能出現?
做法&想法
我們可以窮舉出所有可能的結果,打表。
代碼
代碼就不放了
題目描述
淘淘和藍藍在星際旅行時來到了瓦爾登星,他們們遇到了這裏的原住精靈,意外地發現他們喜歡喫桃子,於是決定將飛船裏的桃子分給他們一些。
精靈一共有N只,編號爲1到N,第i只精靈需要喫Ai個桃子。現在每隻精靈會按1到N的順序領取桃子,每隻精靈可選擇淘淘和藍藍中的一個人,並向他討要桃子。但精靈們也會有情緒,假設前面和自己選了同一個人的精靈討要到的桃子的最大個數是x,如果x大於自己的需求Ai,那麼這個精靈會產生x-Ai的不開心值;如果x不大於自己的需求Ai,那麼這個精靈不會產生不開心值。
淘淘和藍藍想讓所有精靈的不開心值總和最小,他們想問你這個總和的最小值是多少?
做法&想法
我們可以枚舉全排列
代碼
我代碼還是需要放一下,這個是枚舉 的全排列,我們可以使用二進制的方法,就像狀壓 。
我認爲這種寫法比較穩,不會出現爆棧之類的情況。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
int n,a[100010],v1,v2,ans=INT_MAX;
int main(){
read(n);
for(int i=1;i<=n;i++)read(a[i]);
for(int i=0;i<(1<<n);i++){
v1=0;v2=0;int s=0;
for(int j=1;j<=n;j++)
if(i&(1<<(j-1))){
v1=max(v1,a[j]);
if(v1!=a[j])s+=v1-a[j];
}else{
v2=max(v2,a[j]);
if(v2!=a[j])s+=v2-a[j];
}
ans=min(ans,s);
}cout<<ans;
return 0;
}
當然 也是可以的。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
int n,a[100010],v1,v2,ans=INT_MAX,f[100010];
void dfs(int x){
if(x==n+1){
v1=0;v2=0;int s=0;
for(int i=1;i<=n;i++)
if(f[i]==0){
v1=max(v1,a[i]);
if(v1!=a[i])s+=v1-a[i];
}else{
v2=max(v2,a[i]);
if(v2!=a[i])s+=v2-a[i];
}
ans=min(s,ans);
return;
}
f[x]=0;dfs(x+1);
f[x]=1;dfs(x+1);
}
int main(){
read(n);
for(int i=1;i<=n;i++)read(a[i]);
dfs(1);
return 0;
}
有一說一, 種寫法的代碼相似度還是很高的。
題目描述
淘淘來到了一座城市, 這座城市有N個景點,共有N - 1條道路連接着彼此,每個景點到另外一個景點有且僅有一條通路,並且一些道路正在維修,是無法經過的。淘淘開始時可以在任意一個景點,他決定在接下來的K-1天中,每天從當前所在的景點不經過正在維修的道路前往另一個景點(他也可以選擇逗留在原來的景點,也可以去別的景點,並且不限於相鄰的景點,詳見樣例2解釋) ,淘淘希望你求出有多少種不同的旅行方案。
方案數可能很大,因此他要求你求出答案對20200621取模的結果,也就是說,如果你求出了答案Ans,請輸出Ans % 20200621。
做法&想法
首先是 分的做法,我們考慮 。
表示第 天到底第 個點的方案數,我們還可以使用滾的數組,來滾動掉。
我們發現,這個題目需要我們維護連通塊,自然考慮並查集。
我們可以發現,由於每天可以走許多路,所以,
其中, 函數的定義如下:
表示 所在的連通塊節點個數。
代碼
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
const int MOD=20200621;
vector<int>v[100010];
ll n,k,f[100010][2],fa[100010],ans;
int find(int x){
if(fa[x]==x)return x;
return fa[x]=find(fa[x]);
}
int main(){
read(n);read(k);
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<n;i++){
int x,y,z;read(x);read(y);read(z);
if(z)fa[find(x)]=find(y);
}
for(int i=1;i<=n;i++)v[find(i)].push_back(i);
for(int i=1;i<=n;i++)f[i][1]=1;
for(int j=2;j<=k;j++)
for(int i=1;i<=n;i++){
f[i][(j%2)]=0;
for(auto k:v[find(i)])
f[i][j%2]=(f[i][j%2]+f[k][(j-1)%2])%MOD;
}
for(int i=1;i<=n;i++)ans=(ans+f[i][k%2])%MOD;
cout<<ans;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
const int MOD=20200621;
vector<int>v[100010];
ll n,k,f[100010][2],fa[100010],ans,size[100010];
int find(int x){
if(fa[x]==x)return x;
return fa[x]=find(fa[x]);
}
int pw(int x,int y){
int ans=1;
for(;y;y>>=1){
if(y&1)ans=1ll*ans*x%MOD;
x=1ll*x*x%MOD;
}return ans;
}
int main(){
read(n);read(k);
for(int i=1;i<=n;i++)fa[i]=i,size[i]=1;
for(int i=1;i<n;i++){
int x,y,z;read(x);read(y);read(z);
if(z){
size[find(x)]+=size[find(y)];
size[find(y)]=0;
fa[find(y)]=find(x);
}
}
for(int i=1;i<=n;i++)ans=(ans+pw(size[find(i)],k-1))%MOD;
cout<<ans;
return 0;
}
題目描述
淘淘和藍藍在玩一款神奇的遊戲——主地鬥!規則如下:
兩位玩家使用一副撲克牌(一張大王,一張小王,其他牌各四張,共54張)中的一些牌參加遊戲,每人開始有4張手牌,其餘的牌被放在牌堆之中。所有的手牌和牌堆裏牌的順序和點數都被玩家知曉。規定撲克牌的點數大小爲 大王=小王>2>A>K>Q>J>10>9>8>7>6>5>4>3。每局遊戲有數輪。每輪先手會在桌面上放置至少一張,至多不超過後手手牌數量的牌(大王和小王除外),後手可以用點數更大的牌疊在桌面上的牌上(也可以選擇不疊)。若所有桌面上的牌被疊到,則後手獲得此輪勝利,桌面上的牌全部移出遊戲,下一輪遊戲先手變爲後手,後手變爲先手。否則先手獲得此輪勝利,桌面上的牌全部進入後手的手牌(無視手牌上限),下一輪遊戲先手與後手不變。
輪與輪之間,若上一輪的先手的手牌不足4張,將從牌堆頂部拿牌直到手牌爲4張或者牌堆被摸空。
若一輪遊戲開始前。一名玩家沒有手牌而另一名玩家有手牌,那麼沒有手牌的玩家獲得這局遊戲的勝利。如果兩名玩家都有手牌,但是先手玩家只有大王和小王導致他無法放牌,那麼後手玩家獲勝。
因爲總是贏不了淘淘所以淘氣的藍藍準備出老千。
他有以下兩種出千方式:
海底撈月:無視手牌上限從牌堆底部摸一張牌。
偷天換日:將淘淘的任意一張手牌與自己的任意一張牌對調。
出千可以在這局遊戲遊戲開始前進行,並且爲了不被發現,一局遊戲只能出千一次。已知兩名玩家都會按最優策略(即希望獲得本局遊戲勝利,下同)出牌,藍藍會按最優策略出千。(若不出千便能取得勝利,藍藍一定不會出千。若必須出千且兩種方式均能取勝,則優先出海底撈月千)
現在藍藍想問你是否能取得勝利。若取得勝利,是否需要出千,出什麼千。
做法&想法
如此長的題面當然要騙分啦
代碼
騙分( 的好成績)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
int main(){
int a,b;read(a);read(b);
if(a==8&&b==0){puts("Win");puts("No");return 0;}
if(a==9&&b==1){puts("Win");puts("Yes");puts("2");return 0;}
puts("Win");
puts("No");
return 0;
}
略(逃
題目描述
淘淘和藍藍喜歡“歸整”的序列。長度爲N的非負整數序列A是“歸整”的,當且僅當A的任意連續K個元素的和都是S。
我們可以通過修改一些元素來使一個序列變成“歸整”的。可以把A的任意元素修改成0到S之間(包含0和S)的任意整數。淘淘和藍藍想知道至少修改多少個元素才能使序列A變成“歸整”的,於是找到你來幫助他們。
做法&想法
先考慮一個性質:
爲什麼?
首先,
所以,
之後我們就可以開心的 了,我們 表示前 個數和爲 的方案數。
我們可以枚舉第 個數,假設它是 ,那麼
其中, 函數的定義如下:
表示下標和 在模 意義下同餘的數中不爲 的數的個數。
這東西我們可以 預處理出來。
代碼
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
int a[310],ans,f[310][310],h[310][310];
int main(){
memset(f,0x3f,sizeof(f));
int n,k,s;
read(n);read(k);read(s);ans=n;
for(int i=1;i<=n;i++)read(a[i]);
for(int i=0;i<=s;i++)
for(int j=1;j<=n;j++)
h[(j-1)%k+1][i]+=(a[j]!=i);
f[0][0]=0;
for(int i=1;i<=k;i++)
for(int j=0;j<=s;j++)
for(int k=0;k<=j;k++)
f[i][j]=min(f[i][j],f[i-1][j-k]+h[i][k]);
cout<<f[k][s];
return 0;
}
哎,發現自己炸了, 掛成 , 掛成 , 代碼中的第 行 h[i][k]
手滑打成 h[i][j]
關鍵是還能過樣例!氣死我也……
小時的時間是真的短,最後只拍了拍感覺最不穩的 題(結果都沒發現錯誤)
哎, 題掛了 題,我拍題怎麼就沒拍到這 題中的一題呢?
我也不知道。。。
放一放對拍的代碼留作紀念吧。。。
桃子的對拍
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
int n,a[100010],v1,v2,ans=INT_MAX,f[100010],ans1=INT_MAX;
void dfs(int x){
if(x==n+1){
v1=0;v2=0;int s=0;
for(int i=1;i<=n;i++){
if(f[i]==0){
v1=max(v1,a[i]);
if(v1!=a[i])s+=v1-a[i];
}else{
v2=max(v2,a[i]);
if(v2!=a[i])s+=v2-a[i];
}
}
ans1=min(s,ans1);
return;
}
f[x]=0;
dfs(x+1);
f[x]=1;
dfs(x+1);
}
int main(){int s=0;
while(1){n=8;
for(int i=1;i<=n;i++)a[i]=rand()%100+1;
dfs(1);
for(int i=0;i<(1<<n);i++){
v1=0;v2=0;int s=0;
for(int j=1;j<=n;j++){
if(i&(1<<(j-1))){
v1=max(v1,a[j]);
if(v1!=a[j])s+=v1-a[j];
}else{
v2=max(v2,a[j]);
if(v2!=a[j])s+=v2-a[j];
}
}
ans=min(ans,s);
}
if(ans1!=ans){
for(int i=1;i<=n;i++)cout<<a[i];
return 0;
}printf("%d\n",++s);
}
return 0;
}
復讀機的對拍:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
ll gcd(ll x,ll y){
if(x%y==0)return y;
return gcd(y,x%y);
}
ll ans1(ll x,ll z){
ll y=z/x;
while(gcd(x,y)!=1){
int a=gcd(x,y);
y*=a;x/=a;
}
return y;
}
ll ans2(ll x,ll z){
for(int i=1;i<=z;i++){
if(x*i/gcd(i,x)==z)return i;
}
}
int main(){
int s=0;
while(1){
ll x,y,z;x=rand()%100+1;z=(rand()%100+1)*x;
// cout<<x<<" "<<z<<" "<<ans2(x,z)<<endl;
if(ans1(x,z)!=ans2(x,z)){
cout<<x<<" "<<z<<" "<<ans2(x,z)<<endl;
return 0;
}printf("%d\n",++s);
}
return 0;
}
驚喜地發現自己炸成這樣還有 !真是奇蹟,看來我還是不錯的QAQ