1. 程式人生 > 其它 >新風杯20級補題

新風杯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開始的正整數“蛇形”填充無限大的矩陣。

image.png

容易看出矩陣第二行第二列中的數是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;

}


總結

以上題目是自己沒能獨立思考出,看了解析後才寫出來的題目!