台州學院第十二屆校賽記錄(B,C,E,H,I,J,L)

傳送門:點我c++

題目很棒,感謝出題驗題的大佬們。數組

細節坑很多,是好事。ide

仍是很菜,繼續加油!函數

B:學習

桃子的生日

時間限制(普通/Java):1000MS/3000MS     內存限制:65536KByte
總提交: 344            測試經過: 43

描述測試

桃子這幾天在收集記念幣,總共最多隻有N種不一樣的記念幣,他已經收集了K種不一樣的記念幣。這不,桃子的生日快到了,他的M個小夥伴們決定送他記念幣,如何送給桃子呢?他們都贊成了以下三個規則:
spa

1. 每一個人送的記念幣與其餘人的都同樣多;code

2. 送給桃子的任意兩枚記念幣種類均不一樣; blog

3. 桃子從小夥伴那獲得至少L枚的。遞歸

但他的小夥伴們不知道桃子收集了哪些記念幣。他們想盡可能少花錢,因此他們想購買知足規則的最少數量的記念幣。

輸入

第一行一個整數T(≤100),表明有T組數據。

對於每組數據,包含一行爲四個整數N, M, K, L(1≤K≤N≤1018,1≤M,L≤1018),表明有N種不一樣的記念幣,M個小夥伴,桃子原本有K種不一樣的記念幣,最後桃子手上至少有L枚的記念幣。

輸出

輸出桃子的一個小夥伴贈送的最少數量的記念幣。若是不可能同時知足三個條件輸出-1。

樣例輸入

2
20 15 2 3
10 11 2 4

樣例輸出

1
-1

提示

第一組數據:桃子的小夥伴每人送一枚記念幣,由於桃子原來有2種記念幣,小夥伴總共送15枚,必定有至少13枚是新的,知足題目要求且最少。

第二組數據:總共有10種不一樣的記念幣,而桃子的小夥伴有11個,不能知足條件2。

 

思路:

首先,提示告訴咱們若是M>N是直接輸出-1。

很明顯能夠看出K+L是要達到的個數,若是K+L > M,也是能夠直接輸出-1的,由於達不到。

最後直接判斷每一個人送知足條件的個數,會不會超過N便可。具體看代碼有註釋

代碼:

#include<bits/stdc++.h> 
using namespace std;
#define LL long long
#define INF 2000000000
#define eps 1e-8
#define pi  3.141592653589793
const LL mod = 1e9+7;
int main()
{
    int _;
    for(scanf("%d",&_);_--;){
        LL n,m,k,l;
        scanf("%I64d%I64d%I64d%I64d",&n,&m,&k,&l);
        if(m > n){
            puts("-1");continue;
        }
        LL sum = k+l;
        if(sum > n){
            puts("-1");continue;
        }
        LL ans = (sum%m == 0)?sum/m:sum/m+1;//每一個人要送的個數,保證能夠知足K+L
        if(ans * m > n){//若是每一個人送的總數超過了N,根據蜂巢原理一定會重複。因此不行
            puts("-1");continue;
        }
        else{
            printf("%I64d\n",ans);
        }
    }
}
/*
2
100 6 2 98
*/

 

 

C

桃子的難題

時間限制(普通/Java):1000MS/3000MS     內存限制:65536KByte
總提交: 102            測試經過: 6

描述

taozi喜歡數學,可是遇到數學題就頭疼,zdragon爲了讓你們高興高興,給taozi出了道難題:

S=∑q(1≤i≤n),因爲答案可能會很大,答案對p取模。 

輸入

輸入第一行爲測試樣例組數T(1≤T≤100)。

對於每組數據第一行包含三個正整數n,q,p(1≤n,q,p≤109)。

輸出

對於每組數據,輸出一個S對p取模的值。

樣例輸入

2
3 2 100
4 511 520

樣例輸出

14
184

提示

對於第一個樣例,21+22+23=14,對100取模,答案爲14。

 

思路:

S=∑q(1≤i≤n),這玩意首先是個等比數列求和。而後取模,很容易想到套等比數列求和公式,逆元,取模。然而會出錯。。由於可能在模數的意義下可能沒有逆元。

其實是等比數列二分求和處理這玩意(最近寫過同樣的題目因此知道怎麼作)

考慮S=∑q(0≤i≤n),注意是有0.

就是1+q^1+q^2+....q^n

而後當n是偶數的時候:

把這個式子分紅先後相等長度的兩部分

(p^0+p^1+..p^(n/2))+ (p^(n/2+1)+p(n/2+2)+...+p^n)

把後半部分的p^(n/2+1)提取出來。

(p^0+p^1+..p^(n/2)) * (p^(n/2+1)+1)

右邊快速冪,左邊遞歸

奇數的話去掉p^n,一樣的操做去左邊遞歸右邊快速冪。

代碼:

#include<bits/stdc++.h> 
using namespace std;
#define LL long long
#define INF 2000000000
#define eps 1e-8
#define pi  3.141592653589793
long long q(LL a,LL n,LL mod)
{
    LL ans = 1LL,temp = a%mod;
    while(n){
        if(n&1){
            ans=(ans*temp)%mod;
        }
        n>>=1;
        temp=(temp*temp)%mod;
    }
    return ans;
}
LL sum(LL p,LL n,LL mod)
{
    if(p==0)return 0;
    if(n==0)return 1;
    return (n&1)?(((1+q(p,n/2+1,mod))%mod*sum(p,n/2,mod)%mod)%mod):(((1+q(p,n/2+1,mod))%mod*sum(p,n/2-1,mod)+q(p,n/2,mod)%mod)%mod);
}
int main()
{
    /*
        LL a,b,p;
        while(~scanf("%lld %lld %lld",&a,&b,&p)){
                LL sum = 0;for(int i = 1 ; i <= a ; i ++){
                sum += q(b,i,p);
                sum%=p;
            }
            cout<<sum<<endl;
        }
    */
    LL a,b,p;
    int _;
    for(scanf("%d",&_);_--;){
        scanf("%lld %lld %lld",&a,&b,&p);
        LL ans = sum(b,a,p);
        printf("%lld\n",(ans+p-1)%p);
    }
}/*
2
3 2 100
4 511 520
*/

 

E:

YuYu的撲克牌遊戲

時間限制(普通/Java):1000MS/3000MS     內存限制:65536KByte
總提交: 14            測試經過: 3

描述

YuYu最近正在學習多位數的乘法,crq想考考她的學習狀況,但又懶得出題,所以直接拿了一副撲克牌。撲克牌去掉了大小王和牌面值較大的牌,只留下A、二、三、四、五、六、七、8 、9,每種花色有9張牌,牌面值分別爲1~9,現從中抽出n張牌,crq要求YuYu從n張牌中挑出若干張組成乘法公式a*b=c,其中a、b和c都可以由多張牌拼接而成(如1和2能拼成12,也能拼成21),但a和b最可能是2位的正整數(由於YuYu懼怕太大的數)。

如給定4 5 6 9四張牌,能夠組成:

6*9=54

9*6=54

一個公式中同一張牌最多隻能使用一次。

輸入

多組數據,第一行爲數據組數T(T<=100)。

每組數據第一行爲正整數n(n<=36),第二行爲n個正整數,表示從一副牌中抽取的牌面值,全部牌面值在1到9之間。

輸出

對於每組數據,輸出最多有多少種可能的公式。

樣例輸入

2
4
6 9 5 4
5
1 6 6 6 9

樣例輸出

2
4

 

思路:

注意C沒限制是兩位數便可

一眼感受是36^4*100的題,實際100*100兩個循環判斷就好了。

交了打表代碼過了。。不是很懂。

實際我操做的是 一個兩位數乘以一個兩位數等於一個四位數,好比說什麼01*02=0004前面補個0

代碼:

 

#include<bits/stdc++.h> 
using namespace std;
#define LL long long
#define INF 2000000000
#define eps 1e-8
#define pi  3.141592653589793
string change(int a1,int a2,int a3,int a4,int a5,int a6,int a7,int a8){
    string s = "";
    s += (a2+'0');
    s += (a1+'0');
    s += '*';
    s += (a4+'0');
    s += (a3+'0');
    s += '=';
    s += (a8+'0');
    s += (a7+'0');
    s += (a6+'0');
    s += (a5+'0');
    return s;
}
set<string>s;
int main(){
    int _;
    while(~scanf("%d",&_)){
        while(_--){
            s.clear();
    int n,a[40], cnt[12];
    memset(cnt,0,sizeof(cnt));
    scanf("%d",&n);
    for(int i = 0 ; i < n ; i ++){
        scanf("%d",a+i);
        cnt[a[i]]++;
    }
    int sum = 0;
    for(int i = 1 ; i < 100 ; i++){
        for(int j = 1 ; j < 100 ; j++){
            int temp = i;
            int num1 = temp%10;
            int num2 = temp/10%10;
            temp = j;
            int num3 = temp%10;//個位 
            int num4 = temp/10%10;//十位 
            
            temp = i*j;
            int num5 = temp%10;//個位 
            temp/=10;
            int num6 = temp%10;//十位
            temp/=10;
            int num7 = temp%10;//百位
            temp/=10;
            int num8 = temp%10;//千位
            
            if(num1 == 0||num3 == 0||num5 == 0)continue;
            
            if(num8 != 0){
                if(num7 == 0 || num6==0)continue;
            }else{
                if(num7!=0){
                    if(num6==0)continue;
                }
                else{
                    if(num6!=0){
                        if(num5 == 0)continue;
                    }
                }
            }
            //cout<<num8<<num7<<num6<<num5<<endl;
            if(num1 != 0)
                cnt[num1]--;
                
            if(num2 != 0)
                cnt[num2]--;
                
            if(num3 != 0)
                cnt[num3]--;
                
            if(num4 != 0)
                cnt[num4]--;
                
            if(num5 != 0)
                cnt[num5]--;
                
            if(num6 != 0)
                cnt[num6]--;
                
            if(num7 != 0)
                cnt[num7]--;
                
            if(num8 != 0)
                cnt[num8]--;
                    
            if( cnt[num1] >= 0 && cnt[num2] >= 0 &&
                cnt[num3] >= 0 && cnt[num4] >= 0 &&
                cnt[num5] >= 0 && cnt[num6] >= 0 &&
                cnt[num7] >= 0 && cnt[num8] >= 0 ){
                string ss = change(num1,num2,num3,num4,num5,num6,num7,num8);
                   s.insert(ss);
            }
            if(num1 != 0)
                cnt[num1]++;
            if(num2 != 0)
                cnt[num2]++;
            if(num3 != 0)
                cnt[num3]++;
            if(num4 != 0)
                cnt[num4]++;
            if(num5 != 0)
                cnt[num5]++;
            if(num6 != 0)
                cnt[num6]++;
            if(num7 != 0)
                cnt[num7]++;
            if(num8 != 0)
                cnt[num8]++;
        }
    }
//    for(set<string>::iterator it = s.begin() ; it != s.end();it++){
//        cout<<*it<<endl;
//    }
    printf("%d\n",s.size());
}}
}
/*

*/
View Code

 

 

H:

桃子的LCM

時間限制(普通/Java):1000MS/3000MS     內存限制:65536KByte
總提交: 364            測試經過: 64

描述

桃子很喜歡數學,最近他對lcm(最小公倍數)很是感興趣。小翁看到桃子在紙上寫了一大堆數學公式,就想考考桃子。他給小桃出了個題:如今你手上有一個數b,對於每一個1≤a≤1018,他把lcm(a,b)/a的不一樣值寫在了紙上,他想問你,他能在紙上寫幾個不一樣的數字。

輸入

第一行一個整數T(≤50),表明有T組數據。

對於每組數據,第一行一個整數b(1≤n≤1010),表明小桃手上的數b。

輸出

輸出一個數表明不一樣值的個數。

樣例輸入

2
1
2

樣例輸出

1
2

提示

 

第一個樣例,b等於1,只有1個值1。

第二個樣例,b等於2,只有2個值1和2。

 

思路:

打個表(a 從1到b+10 )

就能發現當a > b時候題目那個式子答案都同樣。而後出現的不同的值都是b的約數。因此題目轉化成了求b的約數個數。

(首A拿到了,笑)

複雜度是O(sqrt(n))

代碼:

#include<bits/stdc++.h> 
using namespace std;
#define LL long long
#define INF 2000000000
#define eps 1e-8
#define pi  3.141592653589793
int main()
{
    int n;
    scanf("%d",&n);
    while(n--){
        LL a;int sum = 0;
        scanf("%lld",&a);
        LL k = sqrt(a);
        for(int i = 1 ; i <= k; i++){
            if(a%i==0){
                sum+=2;
            }
        }
        if(k*k==a)sum--;
        printf("%d\n",sum);
    } 
    return 0;
}/*

*/

 

I:

桃子的長號

時間限制(普通/Java):2500MS/7500MS     內存限制:65536KByte
總提交: 347            測試經過: 47

描述

C++課上,老師講到了映射map,桃子以爲映射很神奇,能夠把一個串變成一個數存儲,也能夠把一堆很大的數字變成很小的數字。爲了加深對映射的印象,桃子出了下面這個題:

桃子將給你一個長的十進制數a,包含n個1-9的數字,你有一個映射函數f能夠把x變成f(x)。

你能夠執行如下操做不超過1次:選擇一個非空的連續子段並把裏面的每一個數字x映射成f(x)。例如a=1337,f(1)=1,f(3)=5,f(7)=3,你將選擇區間[2,3],並把3變成f(3)=5,最終獲得1557。

如今你執行了操做不超過1次,你能夠獲得的最大數是多少。

輸入

第一行一個整數T(1≤T≤95),表明有T組數據。

對於每組數據:

第一行爲一個整數n(1≤n≤2*105),爲十進制數a的長度。

第二行爲n個數字組成的整數a:a1a2...an(1≤ai≤9)。

第三行爲9個數字f(1),f(2),...,f(9),表明映射函數f。

數據保證∑n<=106

輸出

每組數據輸出一行,表明桃子能獲得的最大值。

樣例輸入

3
4
1337
1 2 5 4 6 6 3 1 9
5
11111
9 8 7 6 5 4 3 2 1
2
33
1 1 1 1 1 1 1 1 1

樣例輸出

1557
99999
33

 

 

思路:

記第i個數是num[i];

從前日後遍歷第一個f(num[i]) > num[i]的改掉是最優的。而後一個坑的點是,繼續遍歷下去的時候能夠是f(num[pos]) == num[pos]

舉個例子

5

32314

1 4 3 7 1 1 1 1 1

這個數的第四個1要修改爲爲1,可讓第五位的4變成7。

代碼:

 

#include<bits/stdc++.h> 
using namespace std;
#define LL long long
#define INF 2000000000
#define eps 1e-8
#define pi  3.141592653589793
char s[200011];
int main()
{

    int _;
    for(scanf("%d",&_);_--;){
        int n;
        scanf("%d %s",&n,s);
        int f[11];
        for(int i = 1; i <= 9 ;i++){
            scanf("%d",f+i);
        }
        for(int i = 0 ; i < n ; i++){
            int a = s[i] - '0';
            if(f[a] > a){
                int pos = i;
                while(f[a] >= a && pos < n){
                    s[pos] = f[a]+'0';
                    pos++;
                    a = s[pos] - '0';
                }
                break;
            }
        }
        printf("%s\n",s);
    }
}/*
3
4
1337
1 2 5 4 6 6 3 1 9
5
11111
9 8 7 6 5 4 3 2 1
5
32314
1 4 3 7 1 1 1 1 1

*/

 

 

J:

桃子的項鍊

時間限制(普通/Java):1000MS/3000MS     內存限制:65536KByte
總提交: 102            測試經過: 17

描述

桃子喜歡收藏,尤爲是對項鍊有着奇怪的要求:每顆珠子的顏色必須不一樣。因爲各類緣由,他找不到這種項鍊,因此他決定本身給項鍊塗色。

如今他手上有n種不一樣顏色的塗料,項鍊(環形)上有n顆珠子,他想知道他有多少種不一樣的塗法。若一條項鍊能經過繞中心旋轉或翻轉而變成另外一個項鍊,則認爲是同一種塗法。

輸入

輸入第一行爲測試樣例組數T(1<=T<=10000)。

對於每組數據包含一個正整數n(1<=n<=106),表明不一樣顏色的塗料種數或珠子數目。

輸出

對於每組數據,輸出一個整數表明有多少種不一樣的塗法。結果對109+7取模。

樣例輸入

2
3
4

樣例輸出

1
3

 

思路:

打表以後發現是(n!)/2。猜了2發(n+1)*n/2。。。。老老實實打表吧。

n= 1,2時候須要另外判斷。(我是存數組而後直接輸出)

代碼:

 

#include<bits/stdc++.h> 
using namespace std;
#define LL long long
#define INF 2000000000
#define eps 1e-8
#define pi  3.141592653589793
const LL mod = 1e9+7;
LL a[1000011];
int main()
{
    a[0] = a[1] = a[2] = 1;
    for(int i = 3 ; i <= 1000000 ; i++){
        a[i] = (a[i-1] * i)%mod;
    }
    int _;
    for(scanf("%d",&_);_--;){
        int n;
        scanf("%d",&n);
        cout<<a[n-1]<<endl;
    }
}
/*
4
3
4
5
6
*/

 

L:

桃子的幸運彩票

時間限制(普通/Java):1000MS/3000MS     內存限制:65536KByte
總提交: 172            測試經過: 23

描述

最近桃子愛上了博彩,一天他買了一張彩票,上面印着帶有n個數字的序列a1a2a3...an

若是一張彩票是幸運的,當且僅當其知足以下所有條件:

1. 序列能被剛好分紅不相交的至少2段;

2. 每一段區間[l,r]的和都是相同的。

請你幫助桃子判斷他手上的彩票是否是幸運的。

例如123426是幸運的,它能夠分爲3段,12三、42和6,1+2+3=4+2=6。

不相交就是序列的每一個數字剛好屬於一個段。

輸入

第一行一個整數T(≤100),表明有T組數據。

對於每組數據,第一行一個整數n(2≤n≤100),表明彩票中數字序列的位數。

第二行爲一個長度爲n的數字序列a1a2a3...an(0≤ai≤9)。

輸出

若是這張彩票是幸運的,輸出YES,不然輸出NO。

樣例輸入

2
5
73452
4
1248

樣例輸出

YES
NO

提示

第一個樣例:能分紅3段,七、34和52,7=3+4=5+2。

第二個樣例:不能分出。

 

思路:

求個前綴和,暴力枚舉每一個區間可能的和,由於a_i都是很小的!!以後看看看看能不能劃分就好了。

坑點:若是全部的數都是0,也是能夠的。被這個坑了。

代碼:

#include<bits/stdc++.h> 
using namespace std;
#define LL long long
#define INF 2000000000
#define eps 1e-8
#define pi  3.141592653589793
int main()
{

    int _;
    for(scanf("%d",&_);_--;){
        int n;
        scanf("%d",&n);
        string s;cin>>s;
        int a[101],flag = 0;
        int sum[111];
        memset(sum,0,sizeof(sum));
        for(int i = 0 ; i < n ; i++){
            a[i] = s[i] - '0';
            if(i == 0)sum[i+1] = a[i];
            else sum[i+1] = sum[i]+a[i];
        }
        if(sum[n] == 0){
            puts("YES");continue;
        }
        for(int i = 0; i < sum[n]; i ++){
            int pos = 0;
            for(int j = 1 ; j <= n ; j++){
                int nowsum = sum[j] - sum[pos];
                if(nowsum == i){
                    pos = j;
                //    printf("%d %d\n",i,pos);
                }
            }
            if(pos == n || sum[pos] == sum[n]){
                flag = 1;
                break;
            }
        }
        flag ? puts("YES"):puts("NO");
    }
}/*
4
20
00101000021000200100
5
73452
4
1248
8
10101000

1~10

*/
相關文章
相關標籤/搜索