新風杯20級補題
文章目錄
前言
遲來的新風杯補題!大佬出的題很棒哦!
一、喲,在玩石頭剪刀布呢
Description
眾所周知,石頭剪刀布是一款風靡全球的實時競技類遊戲。Herod學長正在觀戰S249世界總決賽,誰知觀戰系統出現了bug,現在只知道對戰雙方(稱為紅方和藍方)分別出了多少次石頭,多少次剪刀,多少次布。在這緊要關頭,Herod學長想請你幫忙編寫一個程式,計算紅方選手最多能贏多少局,以及最少要輸多少局
Input
輸入共有3行
第一行1個整數n表示總共對戰了多少局
第二行3個整數表示紅方出的石頭,剪刀,布的次數
第三行3個整數表示藍方出的石頭,剪刀,布的次數
1≤n≤1000
Output
輸出一行,包含兩個整數,分別表示紅方最多能贏的局數和最少要輸的局數
Sample Input 1
4 1 2 1 2 1 1
Sample Output 1
3 0
Hint
樣例解釋:
贏3局策略:石頭VS剪刀,剪刀VS布,剪刀VS石頭,布VS石頭
輸0局策略:石頭VS石頭,布VS石頭,剪刀VS剪刀,剪刀VS布
Source
Herod
簡單貪心。獲勝的次數很好求。取 min 就行。至於要輸的次數。如果對方出石頭,我方肯定出石頭和布先,石頭和布出完了才出剪刀。這時候就可以算出對方出石頭我方要輸的次數。三種情況的次數加起來就行。
#include<iostream> #include<algorithm> #include<cstring> #include<string.h> #include<cstdio> #include<queue> #include<cmath> using namespace std; int main() { int n; cin>>n; int x1,x2,x3,y1,y2,y3;//石頭,剪刀,布 cin>>x1>>x2>>x3>>y1>>y2>>y3; int win,lose; win=min(x1,y2)+min(x2,y3)+min(x3,y1); lose=max(y1-(x1+x3),0)+max(y2-(x1+x2),0)+max(y3-(x2+x3),0); cout<<win<<" "<<lose<<endl; }
二、喲,是迴文串串文回是
Description
眾所周知,形如:abba,aba這樣的就是迴文串。也就是從左往右看和從右往左看是一樣的,就是迴文串。現在有一個僅由小寫字母組成的字串,想請你找出字串中最長的迴文串長度是多少。
Input
輸入一個字串s
保證字串長度小於等於1000
Output
輸出一行,包含一個整數,表示最長的迴文串長度
Sample Input 1
abbdcdcdac
Sample Output 1
5
Hint
樣例解釋:最長迴文串:dcdcd
Source
Herod
這個思維!!!列舉一個對稱中心,然後往兩邊掃描,直到兩邊端點的字元不相等。計算每次列舉的長度取max。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<cstdio>
#include<queue>
#include<cmath>
using namespace std;
const int MAX=1e4;
char s[MAX];
int ans=0;
void check(int l,int r)
{
int res=0;
while(l>=0&&r<strlen(s))
{
if(s[l]==s[r])
res+=2;
else return ;
if(l==r)
res--;
ans=max(res,ans);
l--;
r++;
}
}
int main()
{
gets(s);
for(int i=1;i<strlen(s);i++)//也可用len=strlen(s)來簡化
{
check(i,i);
check(i,i+1);//兩種可能均有考慮
}
cout<<ans<<endl;
}
三、喲, 我也想參加藍橋杯
蛇形矩陣
Description
眾所周知,藍橋杯大賽每年舉辦一次。作為一名計信學子,很大部分人都會選擇在大二大三參加藍橋杯大賽。為了讓大一的你們之後也能踴躍參加,於是想讓你們提前感受一下藍橋杯的省賽難度。如下圖所示,小明用從1開始的正整數“蛇形”填充無限大的矩陣。
容易看出矩陣第二行第二列中的數是5。請你計算矩陣中第X行第Y列的數是多少?
Input
第一行1個整數t,表示有t組資料
接下來t行,每行兩個整數,分別表示X,Y
1≤t≤100
1≤X,Y≤20
Output
輸出t行,每行包含一個整數,表示矩陣中第X行第Y列 的數
Sample Input 1
2 2 1 3 3
Sample Output 1
3 13
Source
Herod
按照規律,把陣列填滿。然後直接O(1) 輸出就好了。 當然也可以推出一個數學公式 O(1) 計算答案。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<cstdio>
#include<queue>
#include<cmath>
using namespace std;
int main()
{
int a[200][200]={0};
int t,x,y;
cin>>t;
int i=0;//row
int j=0;//colon
int cnt=1;
int flag=1;//方向
while(cnt<=40*40/2)//為什麼是這個值,我想因該是因為x、y的範圍再擴大一點的緣故
{
a[i][j]=cnt;
i-=flag;
j+=flag;
if(flag==1&&i==-1)
{
flag=-1;
i=0;
}
else if(flag==-1&&j==-1)
{
flag=1;
j=0;
}
cnt++;
}
while(t--)
{
cin>>x>>y;
cout<<a[x-1][y-1]<<endl;
}
return 0;
}
四、喲,這就是壓軸題了嘛
揹包問題(dp)
dp還是不熟啊!!!
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<cstdio>
#include<queue>
#include<cmath>
using namespace std;
int a[500],b[500];
int n,ans=0;
void solve(int i,int rem,int sum)//i為選取物品的個數,rem為剩餘可用的錢,sum為總選物品的價值
{
if(i==n)
{
ans=max(ans,sum);
return ;
}
if(rem>=a[i])
solve(i+1,rem-a[i],sum+b[i]);
solve(i+1,rem,sum);
}
int main()
{
int m;
cin>>n>>m;
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=0;i<n;i++)
cin>>b[i];
solve(0,m,0);
cout<<ans<<endl;
return 0;
}
總結
以上題目是自己沒能獨立思考出,看了解析後才寫出來的題目!