1. 程式人生 > >2017-10-1 清北刷題沖刺班a.m

2017-10-1 清北刷題沖刺班a.m

好用 技術 .cn truct main blog esp 沒有 con

位運算1

(bit)

Time Limit:1000ms Memory Limit:128MB

題目描述

LYK擁有一個十進制的數N。它賦予了N一個新的意義:將N每一位都拆開來後再加起來就是N所擁有的價值。例如數字123擁有6的價值,數字999擁有27的價值。

假設數字N的價值是K,LYK想找到一個價值是K-1的數字,當然這個答案實在太多了,LYK想使得這個價值為K-1的數字盡可能大。

輸入格式(bit.in)

一個數N。

輸出格式(bit.out)

一個數表示答案。你需要輸出一個非負整數,且這個數不包含前導0。

輸入樣例1

199

輸出樣例1

198

輸入樣例2

1000

輸出樣例2

0

對於20%的數據n<=10

對於40%的數據n<=100

對於60%的數據n<=1000

對於100%的數據1<=n<=100000。

技術分享
#include<iostream>
#include<cstdio>
using namespace std;
#define maxn 10
int n,bit[maxn],len;
int main(){
    freopen("bit.in","r",stdin);freopen("bit.out","w",stdout);
    scanf(
"%d",&n); while(n){ bit[++len]=n%10; n/=10; } int now=1; while(bit[now]==0)now++; bit[now]--; while(bit[len]==0&&len>=1)len--; if(len==0)printf("0"); else for(int j=len;j>=1;j--)printf("%d",bit[j]); fclose(stdin);fclose(stdout);
return 0; }
100分

火柴棒

(stick)

Time Limit:1000ms Memory Limit:128MB

題目描述

眾所周知的是,火柴棒可以拼成各種各樣的數字。具體可以看下圖:

通過2根火柴棒可以拼出數字“1”,通過5根火柴棒可以拼出數字“2”,以此類推。

現在LYK擁有k根火柴棒,它想將這k根火柴棒恰好用完,並且想知道能拼出的最小和最大的數分別是多少。

輸入格式(stick.in)

一個數k。

輸出格式(stick.out)

兩個數,表示最小的數和最大的數。註意這兩個數字不能有前導0。

輸入樣例

15

輸出樣例

108 7111111

數據範圍

對於30%的數據k<=10。

對於60%的數據k<=20。

對於100%的數據1<k<=100。

技術分享
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int now,anslen=0x7fffffff,ans[101],sum[10];
bool anspre;
struct node{
    int num,cost,cnt;
}q[10];
void dfs(int len,int res){
    if(len>anslen)return;
    if(res==0){
        bool flag=0;
        if(anslen>len)flag=1;
        if(q[6].cnt==len)return;
        anslen=len;
        int lennow=0,ansnow[101];
        for(int i=1;i<=7;i++)sum[i]=q[i].cnt;
        //for(int i=1;i<=7;i++)cout<<sum[i]<<"  ";
        for(int i=2;i<=7;i++){
            if(sum[i]){
                lennow=lennow+1;
                ansnow[lennow]=q[i].num,sum[i]--;
                break;
            }
        }
        for(int i=1;i<=7;i++)
            while(sum[i]){
                lennow=lennow+1;
                ansnow[lennow]=q[i].num,sum[i]--;
            }
        for(int i=1;i<=lennow;i++){
            if(ans[i]>ansnow[i]){
                flag=1;break;
            }
        }
        if(!anspre)flag=1;
        //cout<<anslen<<‘ ‘;cout<<endl;
        if(flag==1){
            for(int i=1;i<=anslen;i++)ans[i]=ansnow[i];
            anspre=1;
        }
        //for(int i=1;i<=anslen;i++)cout<<ansnow[i];cout<<endl;
        return;
    }
    for(int i=1;i<=7;i++){
        if(res-q[i].cost>=0){
            q[i].cnt++;
            dfs(len+1,res-q[i].cost);
            q[i].cnt--;
        }
    }
}
bool cmp(node x,node y){
    return x.num<y.num;
}
int main(){
    //freopen("Cola.txt","r",stdin);
    freopen("stick.in","r",stdin);freopen("stick.out","w",stdout);
    q[1].num=0,q[1].cost=6;
    q[2].num=1,q[2].cost=2;
    q[3].num=2,q[3].cost=5;
    q[4].num=4,q[4].cost=4;
    q[5].num=6,q[5].cost=6;
    q[6].num=7,q[6].cost=3;
    q[7].num=8,q[7].cost=7;
    scanf("%d",&now);
    dfs(0,now);
    for(int i=1;i<=anslen;i++)printf("%d",ans[i]);
    printf(" ");
    if(now%2==1){
        int num=(now-3)/2;
        printf("7");
        for(int i=1;i<=num;i++)printf("1");
    }
    else {
        int num=now/2;
        for(int i=1;i<=num;i++)printf("1");
    }
    fclose(stdin);fclose(stdout);
    return 0;
}
40分 暴力 技術分享
/*
    最大值直接特判一下,最小值用dp解決
    dp[i]表示i根火柴能拼出的最小的數字,枚舉該數字末尾的一位是幾
*/
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <map>
#include <vector>
#include <set>
using namespace std;
long long dp[105];
int f[15],n;
int main()
{
    freopen("stick.in","r",stdin);
    freopen("stick.out","w",stdout);
    f[1]=2; f[2]=5; f[3]=5; f[4]=4; f[5]=5;
    f[6]=6; f[7]=3; f[8]=7; f[9]=6; f[0]=6;
    dp[2]=1; dp[3]=7; dp[4]=4; dp[5]=2; dp[6]=6;dp[7]=8; 
    for (int i=8; i<=100; i++)
    {
        dp[i]=dp[i-f[0]]*10;
      for (int j=0; j<=9; j++)
        if (dp[i-f[j]]!=0)
        dp[i]=min(dp[i],dp[i-f[j]]*10+j);
    }
    cin>>n;
    cout<<dp[n]<< ;
    if (n%2==1) {cout<<7; n-=3;}
    while (n){cout<<1; n-=2;}
    return 0;
}
100分 動態規劃

聽音樂

(music)

Time Limit:1000ms Memory Limit:128MB

題目描述

LYK喜歡聽音樂,總共有n首音樂,有m個時刻,每個時刻LYK會聽其中一首音樂,第i個時刻會聽第ai首音樂。它給自己定了一個規定,就是從聽音樂開始,聽的每連續n首音樂都是互不相同的。例如當n=3時,從聽歌開始,123321就是一個合法的順序(此時LYK聽了兩輪歌,分別是123和321,每一輪的歌都是互不相同的),而121323就是一個不合法的順序(LYK也聽了兩輪歌,第一輪中121存在聽了兩次相同的歌)。我們現在只截取其中一個片段,也就是說並不知道LYK之前已經聽了什麽歌。因此121323也仍然可以是一個合法的順序,因為LYK之前可能聽過3,然後再聽121323,此時LYK聽了三輪歌,分別是312,132和3。

現在LYK將告訴你這m個時刻它聽的是哪首歌。你需要求出LYK在聽這m首歌之前可能聽過的歌的不同方案總數(我們認為方案不同當且僅當之前聽過的歌的數量不同)。LYK向你保證它之前聽過的歌的數量是在0~n-1之間的。因此你輸出的答案也應當是0~n中的某個整數(答案是0表示LYK記錯了,沒有一個合法的方案)。

輸入格式(music.in)

第一行兩個數n,m。

第二行m個數表示ai。

輸出格式(music.out)

一個數表示答案。

輸入樣例1

4 10

3 4 4 1 3 2 1 2 3 4

輸出樣例1

1

樣例解釋1:LYK之前一定只聽過2首歌(12或者21),這樣可以分成3部分分別是34,4132,1234,每一部分都沒有出現相同的歌。對於其它情況均不滿足條件。

輸入樣例2

6 6

6 5 4 3 2 1

輸出樣例2

6

樣例解釋2:LYK之前聽過0~5首歌的任意幾首都是有可能滿足條件的。

數據範圍

對於50%的數據n,m<=1000。

對於100%的數據1<=n,m<=100000,1<=ai<=n。

其中均勻分布著n<m以及n>=m的情況。

提示:

LYK知道這個題目很長,但為了便於理解已經加了很多註釋了……建議沒看懂的同學們再重新看一遍……

技術分享
#include<iostream>
#include<cstdio>
#define maxn 100010
using namespace std;
int n,m,a[maxn],ans;
bool vis[maxn];
int main(){
    //freopen("Cola.txt","r",stdin);
    freopen("music.in","r",stdin);freopen("music.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)scanf("%d",&a[i]);
    for(int i=0;i<n;i++){//枚舉之前聽過的歌的數量 
        bool flag=0;
        for(int j=1;j<=n-i;j++){
            if(vis[a[j]]){
                flag=1;
                break;
            }
            vis[a[j]]=1;
        }
        for(int j=1;j<=n-i;j++)vis[a[j]]=0;
        if(flag)continue;
        for(int j=n-i+1;j<=m;j+=n){//區間起點 
            for(int k=j,l=1;k<=m&&l<=n;k++,l++){
                if(vis[a[k]]){
                    flag=1;
                    break;
                }
                vis[a[k]]=1;
            }
            for(int k=j,l=1;k<=m,l<=n;k++,l++)vis[a[k]]=0;
            if(flag)break;
        }
        if(!flag)ans++;
    }
    printf("%d",ans);
    fclose(stdin);fclose(stdout);
    return 0;
}
50分 暴力

2017-10-1 清北刷題沖刺班a.m