【校內test】桶哥的問題

(以上題目出自_rqy兩年前)html

#A:桶哥的問題——買桶【連接】ios

【題目描述】git

桶哥要買一些全家桶。他有a元錢,而每一個桶要花b元錢。他能不能買到c個桶?數組

【輸入格式】spa

一行三個整數a, b, c
code

【輸出格式】htm

Yes或Noblog

【輸入樣例#1】                    【輸出樣例#1】排序

  26 4 5                                    Yesget

【輸入樣例#2】                    【輸出樣例#2】

3 4 5                                        No

 


顯然這道題很很很簡單的了,而後數據好像也沒有須要特判的(好像有些人特判而後就90pts了qwq)

 思路就是直接b*c與a比,若是b*c≤a,那麼Yes,不然No

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>

using namespace std;

long long a,b,c;//惟一注意要開long long int main(){
    scanf("%lld%lld%lld",&a,&b,&c);
    long long ans = b*c;
    if(ans<=a)cout<<"Yes"<<endl;
    else cout<<"No"<<endl;
    return 0;
}

沒什麼大問題,next~


 

#B:桶哥的問題——送桶【連接】

【題目描述】

桶哥買了n個桶,他要將這些桶送去n我的的家。他送第i個桶須要ai的時間,須要在bi以前送到。桶哥很懶,他想要儘可能晚起身去送桶。問他最晚何時要去送桶?

桶哥在送完一個桶以後能夠緊接着去送另外一個桶。

【輸入格式】

一行一個整數n,如下n行每行兩個整數表示ai,bi。

【輸出格式】

一行一個整數,表示桶哥最晚何時起身。

【輸入樣例】                              【輸出樣例】

4                                                    2
1 6
2 7
2 8
1 7


 

40pts-錯誤思路:把全部ai加起來sum(ai),而後找到一個最大的bi,用bi(max)-sum(ai)能夠得40pts;

90pts-錯誤思路:計算每一個ai與bi的差值,以及bi(max)-sum(ai),取min,能夠騙到90pts;

100pts-正確思路:
對全部的桶按照bi的大小,從小到大排序(對於ai沒有要求)(能夠用sort解決),而後從1~n for循環:求出當前枚舉到的全部ai的和suma,用當前的bi(由於已經排過序了因此當前bi即爲當前最大的bi)減去suma(差值暫且叫它kb),取最小的kb即爲ans;

90pts代碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
const int maxn=1e6+10;

using namespace std;

int n,minn=1e9+7,suma,maxb;

struct tong{
    int a,b,c;
}t[maxn];

bool cmp(tong x,tong y){
    if(x.b==y.b)return x.a>y.a;
    else return x.b<y.b;
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&t[i].a,&t[i].b);
        t[i].c=t[i].b-t[i].a;
        if(t[i].c<minn) minn = t[i].c;
        if(t[i].b>maxb)maxb=t[i].b;
        suma+=t[i].a;
    }
    int sumc=maxb-suma;
    if(sumc<minn)cout<<sumc<<endl;
    else cout<<minn<<endl;
    
    return 0;
}

100pts代碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
const int maxn=1e6+10;

using namespace std;

int n,suma,kb,ans=1e9;

struct tong{
    int a,b,c;
}t[maxn];

bool cmp(tong x,tong y){
    if(x.b==y.b)return x.a>y.a;
    else return x.b<y.b;
}

int main(){
    
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&t[i].a,&t[i].b);
    
    sort(t+1,t+n+1,cmp);
    
    for(int i=1;i<=n;i++){
        suma+=t[i].a;
        kb=t[i].b-suma;
        if(kb<ans) ans=kb;
    }
    
    cout<<ans<<endl;
    
    return 0;
}

#C:桶哥的問題——吃桶【連接】

【題目描述】

桶哥的桶沒有送完,他還有n個桶。他決定把這些桶吃掉。他的每個桶兩個屬性:種類ai和美味值bi。若下標爲x,y,z(下標從1開始)的三個桶知足:

x<z且x+y=z-2y且ax=az

那麼它們構成一個套餐,會產生

(x+z)*(bx-bz

的價值。問:一共會產生多少價值?

【輸入格式】

第一行兩個整數n,m,表示共有m種共n個桶。

第二行n個整數表示bi,

第三行n個整數表示ai。

【輸出格式】

一行一個整數,表示一共會產生多少價值。因爲這個數可能很大,你只須要輸出它除以10007的餘數。若是答案是負的,請將其加上10007再對10007取餘。

【輸入樣例#1】                【輸出樣例#1】

5 2                                       23
6 7 8 7 3
1 2 2 1 2

【輸入樣例#2】                 【輸入樣例#2】

5 2                                        9974
6 3 8 7 7
1 2 2 1 2

【數據範圍】(是個謎)

 


40~50pts思路:

直接暴力模擬這個過程,時間複雜度大概是O(n)的

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
const int maxn=100010;
const int mo=10007;

using namespace std;

int n,m,xb,ans;

struct jgt{
    int a,b,xb;
}t[maxn];

int main(){
    scanf("%d%d",&n,&m);
    
    for(int i=1;i<=n;i++)
      scanf("%d",&t[i].b);
      
    for(int i=1;i<=n;i++)
      scanf("%d",&t[i].a);
      
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            xb=i+j*3;
            if(t[xb].a==t[i].a) ans += ((i+xb)%mo*(t[i].b-t[xb].b)%mo)%mo;
            else continue;
        }
    }
    ans%=mo;ans+=mo;ans%=mo;
    cout<<ans<<endl;
}

100pts:

化簡介個式子,能夠知道x與z mod3 同餘。那麼咱們能夠無論y了,將這n個桶分爲下標mod3餘1,mod3餘2和mod3餘0三種,那麼對於組來講:

這個式子能夠拆成xbx+zbx-xbz-zbz

對於每一項分開枚舉:

xbx:

開兩個數組:c1[]和c[],c1[i]用來儲存第i種桶的xbx是多少,c[i]用來儲存當前枚舉到的全部的第i種桶的xbx的和(每一個xbx只加一遍)

那麼有:

        c1[t[i].a] = (c1[t[i].a]%mod+c[t[i].a]%mod);//存儲xbx 
        //舉個例子:假設mod3餘1的有:(下標,種類,價值)(1,1,6)(4,1,7)(7,1,2),
那麼第一遍:c1[1]=0+0=0;c[1]=0+1*6=6第二遍:
c1[1]=0+6=6;c[1]=6+4*7=32;第三遍:c1[1]=6+32;c[1]=32+14; 這樣恰好每一個x都加了對應的遍數 c[t[i].a] = (c[t[i].a]%mod+(i%mod)*(t[i].b%mod))%mod;

//用來存儲xbx的一遍和。另外要注意把c1放在前面而不是c。

zbx:

開兩個數組:c2[]和c0[],c2[i]用來儲存第i種桶的zbx是多少,c0[i]用來儲存當前枚舉到的全部的第i種桶的bx和;

(啊個人天不知道怎麼表達qwq)

    c2[t[i].a] = (c2[t[i].a]%mod+(i%mod)*(c0[t[i].a])%mod)%mod;//儲存zbx 
        c0[t[i].a] = (c0[t[i].a]%mod+t[i].b)%mod;//用於計算zbx時,儲存bx

xbz:

開兩個數組:c4[]和c3[],c4[i]用來儲存第i種桶的xbz是多少,c3[i]用來儲存當前枚舉到的全部的第i種桶的下標和;

    c4[t[i].a] = (c4[t[i].a]%mod+c3[t[i].a]%mod*t[i].b%mod)%mod;//存儲xbz 
        c3[t[i].a] = c3[t[i].a]%mod+i%mod;//存儲下標的和,用於計算xbz 

zbz:

開兩個數組:c6[]和c5[],c6[i]用來儲存第i種桶的zbz是多少,c5[i]用來儲存當前枚舉到的全部的第i種桶的個數;

  c6[t[i].a] = (c6[t[i].a]%mod+t[i].b%mod*c5[t[i].a]%mod*i%mod)%mod;//儲存zbz
        c5[t[i].a] ++;//記錄第i種桶個數

 

嗯-大概吧:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;

int read() {
  int ans = 0, c, f = 1;
  while (!isdigit(c = getchar()))
    if (c == '-') f *= -1;
  do ans = ans * 10 + c - '0';
  while (isdigit(c = getchar()));
  return ans * f;
}

const int mod=10007;
const int maxn=1000010;
int n,m,ans,ans1;
int c[maxn>>2], c1[maxn>>2], c2[maxn>>2], c3[maxn>>2],c0[maxn>>2],c4[maxn>>2];
int c5[maxn>>2],c6[maxn>>2]; 
struct jgt{
    int a,b;
}t[maxn];


int main(){
    
    scanf("%d%d",&n,&m);
    
    for(int i=1;i<=n;i++)
        scanf("%d",&t[i].b),t[i].b%=mod;
      
    for(int i=1;i<=n;i++)
        scanf("%d",&t[i].a);
    
    for(int i=1;i<=n;i+=3){
        c1[t[i].a] = (c1[t[i].a]%mod+c[t[i].a]%mod);//存儲xbx 
        c[t[i].a] = (c[t[i].a]%mod+(i%mod)*(t[i].b%mod))%mod;//用來存儲xbx的一遍和
        c2[t[i].a] = (c2[t[i].a]%mod+(i%mod)*(c0[t[i].a])%mod)%mod;//儲存zbx 
        c0[t[i].a] = (c0[t[i].a]%mod+t[i].b)%mod;//用於計算zbx時,儲存bx
        c4[t[i].a] = (c4[t[i].a]%mod+c3[t[i].a]%mod*t[i].b%mod)%mod;//存儲xbz 
        c3[t[i].a] = c3[t[i].a]%mod+i%mod;//存儲下標的和,用於計算xbz 
        c6[t[i].a] = (c6[t[i].a]%mod+t[i].b%mod*c5[t[i].a]%mod*i%mod)%mod;
        c5[t[i].a] ++;
    }
    
    for(int i=1;i<=m;i++) 
    ans = (ans%mod+c1[i]%mod+c2[i]%mod-c4[i]-c6[i])%mod;
    
    memset(c, 0, sizeof(c));memset(c0, 0, sizeof(c0));
    memset(c1, 0, sizeof(c1));memset(c2, 0, sizeof(c2));
    memset(c4, 0, sizeof(c4));memset(c3, 0, sizeof(c3));
    memset(c5, 0, sizeof(c5));memset(c6, 0, sizeof(c6));
    
    for(int i=3;i<=n;i+=3){
        c1[t[i].a] = (c1[t[i].a]%mod+c[t[i].a]%mod);//存儲xbx 
        c[t[i].a] = (c[t[i].a]%mod+(i%mod)*(t[i].b%mod))%mod;//用來存儲xbx的一遍和
        c2[t[i].a] = (c2[t[i].a]%mod+(i%mod)*(c0[t[i].a])%mod)%mod;//儲存zbx 
        c0[t[i].a] = (c0[t[i].a]%mod+t[i].b)%mod;//用於計算zbx時,儲存bx
        c4[t[i].a] = (c4[t[i].a]%mod+c3[t[i].a]%mod*t[i].b%mod)%mod;//存儲xbz 
        c3[t[i].a] = c3[t[i].a]%mod+i%mod;//存儲下標的和,用於計算xbz 
        c6[t[i].a] = (c6[t[i].a]%mod+t[i].b%mod*c5[t[i].a]%mod*i%mod)%mod;
        c5[t[i].a] ++;
    }
    
    for(int i=1;i<=m;i++) 
    ans = (ans%mod+c1[i]%mod+c2[i]%mod-c4[i]-c6[i])%mod;
    
    memset(c, 0, sizeof(c));memset(c0, 0, sizeof(c0));
    memset(c1, 0, sizeof(c1));memset(c2, 0, sizeof(c2));
    memset(c4, 0, sizeof(c4));memset(c3, 0, sizeof(c3));
    memset(c5, 0, sizeof(c5));memset(c6, 0, sizeof(c6));
    
    for(int i=2;i<=n;i+=3){
        c1[t[i].a] = (c1[t[i].a]%mod+c[t[i].a]%mod);//存儲xbx 
        c[t[i].a] = (c[t[i].a]%mod+(i%mod)*(t[i].b%mod))%mod;//用來存儲xbx的一遍和
        c2[t[i].a] = (c2[t[i].a]%mod+(i%mod)*(c0[t[i].a])%mod)%mod;//儲存zbx 
        c0[t[i].a] = (c0[t[i].a]%mod+t[i].b)%mod;//用於計算zbx時,儲存bx
        c4[t[i].a] = (c4[t[i].a]%mod+c3[t[i].a]%mod*t[i].b%mod)%mod;//存儲xbz 
        c3[t[i].a] = c3[t[i].a]%mod+i%mod;//存儲下標的和,用於計算xbz 
        c6[t[i].a] = (c6[t[i].a]%mod+t[i].b%mod*c5[t[i].a]%mod*i%mod)%mod;
        c5[t[i].a] ++;
    }
    
    for(int i=1;i<=m;i++) 
    ans = (ans%mod+c1[i]%mod+c2[i]%mod-c4[i]-c6[i])%mod;
    
    printf("%d",(ans+mod)%mod);
    
  }

最後,必定要記得:多取模

敗在了取mod取得少上qwq

end-

相關文章
相關標籤/搜索