1. 程式人生 > >2018C/C++藍橋杯B組省賽

2018C/C++藍橋杯B組省賽

個人理解,僅供參考,歡迎討論

(2)

標題:明碼

漢字的字形存在於字型檔中,即便在今天,16點陣的字型檔也仍然使用廣泛。
16點陣的字型檔把每個漢字看成是16x16個畫素資訊。並把這些資訊記錄在位元組中。

一個位元組可以儲存8位資訊,用32個位元組就可以存一個漢字的字形了。
把每個位元組轉為2進製表示,1表示墨跡,0表示底色。每行2個位元組,
一共16行,佈局是:

第1位元組,第2位元組
第3位元組,第4位元組
....
第31位元組, 第32位元組

這道題目是給你一段多個漢字組成的資訊,每個漢字用32個位元組表示,這裡給出了位元組作為有符號整數的值。

題目的要求隱藏在這些資訊中。你的任務是復原這些漢字的字形,從中看出題目的要求,並根據要求填寫答案。

這段資訊是(一共10個漢字):
4 0 4 0 4 0 4 32 -1 -16 4 32 4 32 4 32 4 32 4 32 8 32 8 32 16 34 16 34 32 30 -64 0
16 64 16 64 34 68 127 126 66 -124 67 4 66 4 66 -124 126 100 66 36 66 4 66 4 66 4 126 4 66 40 0 16
4 0 4 0 4 0 4 32 -1 -16 4 32 4 32 4 32 4 32 4 32 8 32 8 32 16 34 16 34 32 30 -64 0
0 -128 64 -128 48 -128 17 8 1 -4 2 8 8 80 16 64 32 64 -32 64 32 -96 32 -96 33 16 34 8 36 14 40 4
4 0 3 0 1 0 0 4 -1 -2 4 0 4 16 7 -8 4 16 4 16 4 16 8 16 8 16 16 16 32 -96 64 64
16 64 20 72 62 -4 73 32 5 16 1 0 63 -8 1 0 -1 -2 0 64 0 80 63 -8 8 64 4 64 1 64 0 -128
0 16 63 -8 1 0 1 0 1 0 1 4 -1 -2 1 0 1 0 1 0 1 0 1 0 1 0 1 0 5 0 2 0
2 0 2 0 7 -16 8 32 24 64 37 -128 2 -128 12 -128 113 -4 2 8 12 16 18 32 33 -64 1 0 14 0 112 0
1 0 1 0 1 0 9 32 9 16 17 12 17 4 33 16 65 16 1 32 1 64 0 -128 1 0 2 0 12 0 112 0
0 0 0 0 7 -16 24 24 48 12 56 12 0 56 0 -32 0 -64 0 -128 0 0 0 0 1 -128 3 -64 1 -128 0 0

注意:需要提交的是一個整數,不要填寫任何多餘內容。

負數的二進位制等於 原碼取反 再加1 eg:-1 -> 00000001 -> 11111110 ->11111111

利用bitset庫函式一步到位

#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <bits/stdc++.h>
typedef long long LL;
const int N =1e5+100;
using namespace std;
typedef long long LL;
const
LL mod = 1000000009; int main() { freopen("1.txt","r",stdin); for(int j=0; j<10; j++) { for(int i=0; i<16; i++) { for(int k=0; k<2; k++) { int x; cin>>x; bitset<8>b(x); string str=b.to_string(); for(int i=0;i<str.length();i++) { if(str[i]=='1')cout<<"."; else cout<<" "; } } cout<<endl; } } return 0; }

手動模擬

#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <bits/stdc++.h>
typedef long long LL;
const int N =1e5+100;
using namespace std;
typedef long long LL;
const LL mod =  1000000009;
char str[200][50];
int a[200];

int main()
{
    freopen("1.txt","r",stdin);
    for(int i=0;i<160;i++)a[i]=0;
    int b[10];
    int o=0;
    for(int j=0; j<10; j++)
    {
        for(int i=0; i<16; i++,o++)
        {
            if(j==0&&i==4)
            {
                int cnt=0;
                cnt++;
            }
            for(int k=0; k<2; k++)
            {
                //if(j==0)
                int x;
                scanf("%d", &x);
                memset(b,0,sizeof(b));
                if(x<0)
                {
                    int h=0;
                    x=-x;
                    while(x)
                    {
                        int y=x%2;
                        b[h++]=y;
                        x/=2;
                    }
                    for(int r=7; r>=0; r--)
                    {
                        if(b[r]==0)b[r]=1;
                        else b[r]=0;
                    }
                    x=0;
                    for(int r=7; r>=0; r--) x=x*2+b[r];
                    x+=1;
                    memset(b,0,sizeof(b));
                    h=0;
                    while(x)
                    {
                        int y=x%2;
                        b[h++]=y;
                        x/=2;
                    }
                    for(int r=7; r>=0; r--)
                    {
                        if(r>=0&&b[r]!=0)str[o][a[o]++]='.';
                        else str[o][a[o]++]=' ';
                    }
                }
                else
                {
                    int h=0;
                    while(x)
                    {
                        int y=x%2;
                        b[h++]=y;
                        x/=2;
                    }
                    for(int r=7; r>=0; r--)
                    {
                        if(r>=0&&b[r]!=0)str[o][a[o]++]='.';
                        else str[o][a[o]++]=' ';
                    }
                }
            }
            str[o][a[o]++]=' ';
        }
    }
    for(int i=0;i<160;i++)
    {
        printf("%s\n",str[i]);
        if((i+1)%16==0)puts(""),puts("");
    }

    return 0;
}

(4)
標題:測試次數

x星球的居民脾氣不太好,但好在他們生氣的時候唯一的異常舉動是:摔手機。
各大廠商也就紛紛推出各種耐摔型手機。x星球的質監局規定了手機必須經過耐摔測試,並且評定出一個耐摔指數來,之後才允許上市流通。

x星球有很多高聳入雲的高塔,剛好可以用來做耐摔測試。塔的每一層高度都是一樣的,與地球上稍有不同的是,他們的第一層不是地面,而是相當於我們的2樓。

如果手機從第7層扔下去沒摔壞,但第8層摔壞了,則手機耐摔指數=7。
特別地,如果手機從第1層扔下去就壞了,則耐摔指數=0。
如果到了塔的最高層第n層扔沒摔壞,則耐摔指數=n

為了減少測試次數,從每個廠家抽樣3部手機參加測試。

某次測試的塔高為1000層,如果我們總是採用最佳策略,在最壞的運氣下最多需要測試多少次才能確定手機的耐摔指數呢?

請填寫這個最多測試次數。

注意:需要填寫的是一個整數,不要填寫任何多餘內容。

這題是51nod上的一道原題
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1306
主要要轉換思想,題目問最多需要多少次(就是一定能測出來),轉換為給你一定的物品數量和測試次數能測試的最大高度,即這個高度一定能被測試出來
dp[i][j] (i個物品j次嘗試) dp[i][j]=dp[i-1][j-1]+1+dp[i][j-1];
即在某個高度摔一次碎了,若要一定能測出來那麼這個高度是dp[i-1][j-1]+1
若沒碎即這個高度再加上能測得最大高度dp[i-1][j-1]+1+dp[i][j-1];
這篇部落格說的很清楚一定能看懂 http://blog.sina.com.cn/s/blog_3fe961ae0101llmf.html

(10)標題:乘積最大
給定N個整數A1, A2, … AN。請你從中選出K個數,使其乘積最大。
請你求出最大的乘積,由於乘積可能超出整型範圍,你只需輸出乘積除以1000000009的餘數。
,如果X<0, 我們定義X除以1000000009的餘數是負(-X)除以1000000009的餘數。
即:0-((0-x) % 1000000009)
【輸入格式】
第一行包含兩個整數N和K。
以下N行每行一個整數Ai。
對於40%的資料,1 <= K <= N <= 100
對於60%的資料,1 <= K <= 1000
對於100%的資料,1 <= K <= N <= 100000 -100000 <= Ai <= 100000
【輸出格式】
一個整數,表示答案。

【輸入樣例】
5 3
-100000
-10000
2
100000
10000

【輸出樣例】
999100009

再例如:
【輸入樣例】
5 3
-100000
-100000
-2
-100000
-100000

【輸出樣例】
-999999829
題目是要求解最大最後取模,我給看成取模後解最大。。
把正負數分成兩個陣列處理出來;
判斷結果是正還是負
(1)結果為負數,兩個陣列按絕對值從小到大排序取k個即可
當k=n時,如果負數的個數為奇數一定為負
當k小於n時,只有k取奇數且n個數全為負數結果為負,因為可以通過正負數的個數來調整
(2)結果為正數,兩個陣列按照絕對值從大到小排列,
當k是奇數,先取一個正數,然後每次取一對正數 一對負數比較大小選擇大的
當不夠一對時不選當前陣列

#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <bits/stdc++.h>
typedef long long LL;
const int N =1e5+100;
using namespace std;
typedef long long LL;
const LL mod =  1000000009;
LL a[N], b[N];
int cmp(int x,int y)
{
    return -x>-y;
}
int cmp1(int x,int y)
{
    return x>y;
}

int main()
{
    LL n, k;
    scanf("%lld %lld", &n, &k);
    int k1=0, k2=0;
    LL s1=1;
    for(int i=0; i<n; i++)
    {
        LL x;
        scanf("%lld", &x);
        if(x>=0) a[k1++]=x;
        else b[k2++]=x;
        s1=s1*x%mod;
    }
    LL ans=1;
    int l1=0, l2=0;
    if(k==n) ans=s1;
    else if(k1==0&&k%2==1)
    {
        sort(b,b+k2,cmp1);
        for(int i=0; i<k; i++)ans=ans*b[i]%mod;
    }
    else
    {
        sort(a,a+k1,cmp1);
        if((k&1)&&k1!=0) ans=a[l1++],k--;
        while(k>1)
        {
            LL h1=-1, h2=-1;
            if(k1-l1>=1)h1=a[l1]*a[l1+1]%mod;
            if(k2-l2>=1)h2=b[l2]*b[l2+1]%mod;
            if(h1==-1&&h2==-1)break;
            if(h1>h2) ans=ans*h1%mod, l1=l1+2;
            else ans=ans*h2%mod, l2=l2+2;
            k-=2;
        }
    }
    printf("%lld\n",ans);
    return 0;
}