天天看點

重走長征路---OI每周刷題記錄---9月29日 2013 AC 20題

總目錄詳見https://blog.csdn.net/mrcrack/article/details/84471041

做題原則,找不到測評位址的題不做。2018-11-28

重走長征路---OI每周刷題記錄---9月29日  2013

本周共計20題

測評位址:

bfs

1.細胞問題  //線上測評位址https://www.luogu.org/problemnew/show/P1451

2.Knight Moves  //線上測評位址https://vjudge.net/problem/POJ-1915

dfs

3.特殊的質數肋骨  //線上測評位址https://www.luogu.org/problemnew/show/P1218

高精度

階乘統計

4.階乘統計  //線上測評位址http://codevs.cn/problem/2156/

5.階乘末尾的零  //線上測評位址http://codevs.cn/problem/2860/

6.階乘問題  //線上測評位址https://www.luogu.org/problemnew/show/P1134

7.計算n!的值  //線上測評位址https://www.luogu.org/problemnew/show/P1009​​​​​​​

貪心

8.裝箱問題  //線上測評位址https://www.luogu.org/problemnew/show/P1049

dp

數字三角形2-4

9.數字三角形2  //線上測評位址http://codevs.cn/problem/2189/

10.數字三角形3  //線上測評位址http://codevs.cn/problem/2193/

11.數字三角形4  //線上測評位址http://codevs.cn/problem/2198/

12.最長不下降子序列  //線上測評位址http://codevs.cn/problem/1576/

13.最小中間和  //線上測評網站http://codevs.cn/problem/1382/

14.飛彈問題  //線上測評位址https://www.luogu.org/problemnew/show/P1020

15.均分紙牌  //線上測評位址https://www.luogu.org/problemnew/show/P1031

16.機器工廠  //線上測評位址https://www.luogu.org/problemnew/show/P1376

17.機器配置設定  //線上測評位址https://www.luogu.org/problemnew/show/P2066

dfs

18.素數環   //線上測評位址https://vjudge.net/problem/HDU-1016

模拟

19.黑色星期五  //線上測評位址https://www.luogu.org/problemnew/show/P1202

20.單數?雙數?  //線上測評位址http://codevs.cn/problem/2163/

題解:

bfs

1.細胞問題

//P1451 求細胞數量

//線上測評位址https://www.luogu.org/problemnew/show/P1451

//每bfs一次,算一個細胞,同時把遇到的非0值置0

//算法的時間複雜度,若測試資料整個為1個細胞,100*100*(100)=10^6

//若測試資料整個為0個細胞,100*100=10^4

//樣例通過,送出AC。2018-12-10

#include <stdio.h>

#include <string.h>

char s[110][110];

int next[][2]={{-1,0},{1,0},{0,-1},{0,1}};//上下左右

int vis[110][110],m,n;//突然想到vis[][]還可以有二維形式,開竅了。

struct Point{

    int x,y;

}q[12000],p;

void bfs(int x,int y){

    int h,t,nx,ny,i;

    h=t=1;

    q[t].x=x,q[t].y=y,vis[x][y]=1,s[x][y]='0',t++;

    while(h<t){

        p=q[h];

        for(i=0;i<4;i++){

            nx=p.x+next[i][0];

            ny=p.y+next[i][1];

            if(0<=nx&&nx<m&&0<=ny&&ny<n&&vis[nx][ny]==0&&s[nx][ny]!='0'){

                s[nx][ny]='0',vis[nx][ny]=1;

                q[t].x=nx,q[t].y=ny,t++;

            }

        }

        h++;

    }

}

int main(){

    int i,j,cnt=0;

    memset(vis,0,sizeof(vis));

    scanf("%d%d",&m,&n);

    for(i=0;i<m;i++)

        scanf("%s",s[i]);

    for(i=0;i<m;i++)//此處寫成 for(i=0;i<n;i++) 昏招

        for(j=0;j<n;j++)//此處寫成 for(j=0;j<m;j++) 昏招

            if(s[i][j]!='0'){

                cnt++;

                bfs(i,j);

            }

    printf("%d\n",cnt);

    return 0;

}

2.Knight Moves

//Knight Moves POJ - 1915 

//線上測評位址https://vjudge.net/problem/POJ-1915 

//借助 題圖,樣例,還是弄懂了該題。一個單詞都沒查 

//寫代碼的過程有些失誤,但還是通過靜态檢查找到了問題。 

//q[t].s=s+1,t++;//此處寫成 t++,q[t].s=s+1;

//樣例通過,送出Runtime Error。

//仔細看了看,大意了, q[100000];//此處寫成 q[10000]

//修改,送出AC。2018-12-10 20:23

#include <stdio.h>

#include <string.h>

int next[][2]={{-1,-2},{-2,-1},{-2,1},{-1,2},{1,-2},{2,-1},{2,1},{1,2}};

int vis[310][310],n;

struct Point{

    int r,c,s;

}q[100000];//此處寫成 q[10000]

void bfs(int sr,int sc,int er,int ec){

    int h,t,r,c,s,i,nr,nc;

    h=t=1;

    q[t].r=sr,q[t].c=sc,q[t].s=0,t++,vis[sr][sc]=1;

    while(h<t){

        r=q[h].r,c=q[h].c,s=q[h].s;

        if(r==er&&c==ec){

            printf("%d\n",s);

            return;

        }

        for(i=0;i<8;i++){

            nr=r+next[i][0],nc=c+next[i][1];

            if(0<=nr&&nr<n&&0<=nc&&nc<n&&vis[nr][nc]==0){

                vis[nr][nc]=1,q[t].r=nr,q[t].c=nc,q[t].s=s+1,t++;//此處寫成 t++,q[t].s=s+1;

            }

        }

        h++;

    }

}

int main(){

    int t,sr,sc,er,ec;

    scanf("%d",&t);

    while(t--){

        memset(vis,0,sizeof(vis));

        scanf("%d",&n);

        scanf("%d%d%d%d",&sr,&sc,&er,&ec);

        bfs(sr,sc,er,ec);

    }

    return 0;

}

dfs

3.特殊的質數肋骨

//P1218 [USACO1.5]特殊的質數肋骨 Superprime Rib

//線上測評位址https://www.luogu.org/problemnew/show/P1218

//一開始想用質數篩,但一看99999999,即10^9,O(n)明顯逾時

//還是用深搜。

//原以為會挺慢,測試下來,速度驚人。樣例通過,送出AC。2018-12-12

//該題還有一個辦法,打表。

#include <stdio.h>

#include <string.h>

int n,a[15];

int isPrime(int x){//質數 傳回1,非質數傳回 0

    int i;

    if(x==1)return 0;

    if(x==2)return 1;

    for(i=2;i*i<=x;i++)

        if(x%i==0)return 0;

    return 1;

}

void dfs(int step){

    int i,k,ans;

    if(step==n+1){

        ans=0;

        for(k=1;k<=n;k++)//此處寫成 for(k=1;k<=n;i++) 真是昏到家了。

            ans*=10,ans+=a[k];

        if(isPrime(ans))printf("%d\n",ans);

        return ;

    }

    for(i=1;i<=9;i++){

        ans=0,a[step]=i;//此處寫成a[k]=i//漏了此句a[k]=i

        for(k=1;k<=step;k++)

            ans*=10,ans+=a[k];

        if(isPrime(ans))

            dfs(step+1);

    }

}

int main(){

    scanf("%d",&n);

    dfs(1);

    return 0;

}

高精度

階乘統計

4.階乘統計

//2156 階乘統計

//線上測評位址http://codevs.cn/problem/2156/

//long long 2^63=9223372036854775808

//           20!=2432902008176640000

//故,該題long long不會溢出

//對long long與int混搭,心存疑慮,立馬測試,之後解惑。

//樣例通過,送出AC。2018-12-10

#include <stdio.h>

#define LL long long

int out[20];//輸出的數

int main(){

    LL ans=1,b;

    int n,k,i,len;

    scanf("%d%d",&n,&k);

    for(i=1;i<=n;i++)

        ans*=i;

    while(ans%10==0)ans/=10;//去尾部的0

    len=0,b=ans;

    while(b){

        out[len++]=b%10;

        b/=10;

    }

    if(k>=len)printf("%lld",ans);

    else

        for(i=k-1;i>=0;i--)

            printf("%d",out[i]);

    return 0;

}

5.階乘末尾的零

//2860 階乘末尾的零

//線上測評位址http://codevs.cn/problem/2860/

//思路,統計每個數的因數10,5,2的個數

//每一對2,5對應一個結果0,每一個10對應一個結果0

//注意:1000!有249個零。

//考慮統計用long long

//擔心10^8會逾時,測試了一下,估計能險過

//送出AC.2018-12-10

#include <stdio.h>

#include <string.h>

#define LL long long

int min(LL a,LL b){

    return a<b?a:b;

}

int main(){

    LL cnt_2=0,cnt_5=0,cnt_10=0;

    int i,n,m;

    scanf("%d",&n);

    for(i=1;i<=n;i++){

        m=i;

        while(m%10==0)m/=10,cnt_10++;

        while(m%5==0)m/=5,cnt_5++;

        while(m%2==0)m/=2,cnt_2++;

    }

    printf("%lld\n",cnt_10+min(cnt_2,cnt_5));

    return 0;

}

6.階乘問題

//P1134 階乘問題

//線上測評位址https://www.luogu.org/problemnew/show/P1134

//思路,統計每個數的因數5,2的個數

//每一個10對應一個結果0若該數是10的整數倍,可直接跳過,不影響結果

//每一對2,5對應一個結果0,

//注意:注意:10,000,000!有2499999個零。

//考慮統計用long long

//擔心5*10^7會逾時,測試了一下,估計能險過

//送出AC.2018-12-10 對此次算法表示滿意,全是自己編的。

#include <stdio.h>

#define LL long long

int main(){

    LL cnt_2=0,cnt_5=0,i;

    int n,m,ans=1;

    scanf("%d",&n);

    for(i=1;i<=n;i++){

        m=i;

        if(m%10==0)m/=10;

        while(m%5==0)m/=5,cnt_5++;

        while(m%2==0)m/=2,cnt_2++;

        ans=(ans*m)%10;

    }

    if(cnt_2>cnt_5)

        for(i=1;i<=cnt_2-cnt_5;i++)

            ans=(ans*2)%10;

    else if(cnt_2<cnt_5)

        for(i=1;i<=cnt_5-cnt_2;i++)

            ans=(ans*5)%10;

    printf("%d\n",ans);

    return 0;

}

7.計算n!的值

//P1009 階乘之和

//線上測評位址https://www.luogu.org/problemnew/show/P1009

//看完題目,就知道該用,高精度加法+高精度乘法 

//用高精度,總感覺挺糟糕的,代碼量不小啊 

//該開多大的數組呢,先開大的吧,開到int z[2000] 

//之後,測試n=50,再将上述數組 縮小範圍。 

//循環次數,外層循環(1+50)*50/2=1275,内部循環,大約沒算一次大約1000,大緻感覺不會逾時 

//先編一個主體程式,再編高精度乘,隻有才是高精度加 

//編的過程中,記得及時測試,否則,怎麼錯都不知道。 

//該題的優點是,高精度乘 發生在 數字*整數數組,編起來,相對簡單些

//為了盡可能的避免,運算過程中int的溢出,準備對f[]采用long long

//突然想到n!=(n-1)!*n應該能省不少時間

//z[i]+=y[i]+x[i];//此處寫成z[i]=y[i]+x[i];查了好久 花了30分鐘。 

//測試了50的答案為31035053229546199656252032972759319953190362094566672920420940313

//maxn 開到 100即可

//測了一下,n=500反應也很快。決定将maxn開到1000

//樣例通過,送出AC。2019-1-15 21:13

//翻看了之前,編寫的代碼,在伯仲之間,各有優缺點。

//詳見https://blog.csdn.net/mrcrack/article/details/78473644

//1173 階乘和 

#include <stdio.h>

#include <string.h>

#define maxn 1000

#define LL long long

LL f[maxn],ans[maxn],g[maxn];

void mul(int a,LL *f){

    int i;

    for(i=1;i<=f[0];i++)f[i]*=a;

    for(i=1;i<=f[0];i++){//進位處理

        f[i+1]+=f[i]/10;

        f[i]%=10; 

    }

    if(0<f[i]&&f[i]<10)f[0]=i;

    else if(f[i]>=10){

        while(f[i]>=10){

            f[i+1]+=f[i]/10;

            f[i]%=10;

            i++;

        }

        f[0]=i;

    }

}

void add(LL *x,LL *y,LL *z){

    int i;

    z[0]=y[0]>x[0]?y[0]:x[0];

    for(i=1;i<=z[0];i++){

        z[i]+=y[i]+x[i];//此處寫成z[i]=y[i]+x[i];查了好久 

        z[i+1]+=z[i]/10;

        z[i]%=10;

    }

    if(z[i])z[0]=i;

}

int main(){

    int n,i;

    memset(ans,0,sizeof(0));

    scanf("%d",&n);

    memset(f,0,sizeof(f));

    f[0]=1,f[1]=1;

    for(i=1;i<=n;i++){

        mul(i,f);

        memset(g,0,sizeof(g));//漏了此句 

        add(f,ans,g);

        memcpy(ans,g,sizeof(g));

    }

    for(i=ans[0];i>=1;i--)printf("%lld",ans[i]);

    return 0;

}

貪心

8.裝箱問題

//P1049 裝箱問題

//NOIP 2001 普及組 

//線上測評位址https://www.luogu.org/problemnew/show/P1049 

//01背包問題,将物品的體積看成體積、價值即可。 

//樣例通過,送出AC。2018-12-9 15:31 

#include <stdio.h>

#include <string.h>

int v[35],f[35][20100];

int max(int a,int b){

    return a>b?a:b;

}

int main(){

    int m,n,i,j;

    memset(f,0,sizeof(f));

    scanf("%d%d",&m,&n);

    for(i=1;i<=n;i++)

        scanf("%d",&v[i]);

    for(i=1;i<=n;i++)

        for(j=0;j<=m;j++)

            if(j<v[i])

                f[i][j]=f[i-1][j];

            else

                f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+v[i]);

    printf("%d\n",m-f[n][m]);

    return 0;

}

dp

數字三角形2-4

9.數字三角形2

//2189 數字三角形W

//線上測評位址http://codevs.cn/problem/2189/ 

//沒什麼好辦法,深搜dfs 

//擔心的是,逾時,試試看吧,沒有辦法的辦法 

//該題,節點上最大值未告知,不過還是能應付的,a[i][j]%=100;//防止資料計算int溢出 100*25=2500

//樣例通過,送出,測試點1,2WA。2019-1-14 20:24

//發現問題,dfs(a[1][1],1,1,1);//此處寫成 dfs(0,1,1,1); 

//修改,送出AC。2019-1-14 20:35 

#include <stdio.h>

#include <string.h>

int n,a[30][30],b,c,sum,ans=0;

int max(int a,int b){

    return a>b?a:b;

}

void dfs(int sum,int step,int r,int c){//r行 c列 

    int i,j;

    if(step==n){

        ans=max(ans,sum%100);

        return ;

    }

    for(j=0;j<2;j++)

        dfs(sum+a[r+1][c+j],step+1,r+1,c+j);

}

int main(){

    int i,j;

    memset(a,0,sizeof(a));

    scanf("%d",&n);

    for(i=1;i<=n;i++)

        for(j=1;j<=i;j++){

            scanf("%d",&a[i][j]);

            a[i][j]%=100;//防止資料計算int溢出 100*25=2500 

        }

    dfs(a[1][1],1,1,1);//此處寫成 dfs(0,1,1,1);

    printf("%d\n",ans);

}

10.數字三角形3

//2193 數字三角形WW

//線上測評位址http://codevs.cn/problem/2193/

//一度想放棄,想看懂 數字三角形2 遞推的解答,

//試圖用在 該題上,無奈,一時難以看懂,隻好回到深搜dfs的老路上。

//在想,在亂搜中,如何過指定的點,遇到非指定點就跳過去,

//一個想法突然冒出來,這不就是剪枝嗎,太高興了,算法有了。2019-1-15 06:08

//該題有個缺點,沒說節點的最大值,在考慮int是否溢出

//樣例通過,送出AC。2019-1-15 剪枝有些感覺了

#include <stdio.h>

#include <string.h>

#define maxn 30

int n,a[maxn][maxn],ans=-999999999;

int max(int a,int b){

    return a>b?a:b;

}

void dfs(int step,int sum,int r,int c){

    int j;

    if(r==n/2&&c!=n/2)//剪枝

        return;

    if(step==n){

        ans=max(ans,sum);

        return ;

    }

    for(j=0;j<2;j++)

        dfs(step+1,sum+a[r+1][c+j],r+1,c+j);

}

int main(){

    int i,j;

    scanf("%d",&n);

    for(i=1;i<=n;i++)

        for(j=1;j<=i;j++)

            scanf("%d",&a[i][j]);//此處寫成scanf("%d",&a[i]);,昏招

    dfs(1,a[1][1],1,1);

    printf("%d\n",ans);

    return 0;

}

11.數字三角形4

//2198 數字三角形WWW

//線上測評位址http://codevs.cn/problem/2198/

//有了 剪枝 這個 技能,該題也就有信心了。

//該題的問題是,節點的最大值是多少,沒說,存在int可能溢出的情況。

//樣例通過,送出AC。2019-1-15 08:39

#include <stdio.h>

#include <string.h>

#define maxn 30

int n,a[maxn][maxn],x,y,ans=-999999999;

int max(int a,int b){

    return a>b?a:b;

}

void dfs(int sum,int step,int r,int c){

    int j;

    if(r==x&&c!=y)return;//剪枝

    if(step==n){

        ans=max(ans,sum);

        return ;

    }

    for(j=0;j<2;j++)

        dfs(sum+a[r+1][c+j],step+1,r+1,c+j);

}

int main(){

    int i,j;

    memset(a,0,sizeof(a));

    scanf("%d",&n);

    for(i=1;i<=n;i++)

        for(j=1;j<=i;j++)

            scanf("%d",&a[i][j]);

    scanf("%d%d",&x,&y);

    dfs(a[1][1],1,1,1);

    printf("%d\n",ans);

    return 0;

}

12.最長不下降子序列

//最長不下降子序列 此題不好找,無奈找下題替換

//1576 最長嚴格上升子序列

//線上測評位址http://codevs.cn/problem/1576/

//樣例通過,送出AC。2018-12-19

#include <stdio.h>

#define maxn 5100

int a[maxn],d[maxn];

int max(int a,int b){

    return a>b?a:b;

}

int main(){

    int n,i,j,len=-1;

    scanf("%d",&n);

    for(i=1;i<=n;i++)

        scanf("%d",&a[i]);

    for(i=1;i<=n;i++){

        d[i]=1;

        for(j=1;j<i;j++)

            if(a[j]<a[i]&&d[j]+1>d[i])

                d[i]=d[j]+1,len=max(len,d[i]);

    }

    printf("%d\n",len);

    return 0;

}

13.最小中間和

//最小中間和 找不到 線上測評,隻好找 基本類似 來替換

//1382 沙子合并

//線上測評網站http://codevs.cn/problem/1382/

//f[i][j] i->j之間的 最小和

//開一個字首和b[i] 1->i的和

//f[i][i]=0;//此處真是,神來之筆

//最小的中間和的動歸,完全是獨立想出,高興。

//樣例通過,送出AC。2018-12-21

#include <stdio.h>

#include <string.h>

#define maxn 310

int a[maxn],f[maxn][maxn],b[maxn];

int min(int a,int b){

    return a<b?a:b;

}

int main(){

    int i,j,n,k;

    scanf("%d",&n);

    memset(f,127,sizeof(f)),b[0]=0;

    for(i=1;i<=n;i++){

        scanf("%d",&a[i]);

        f[i][i]=0;//此處真是,神來之筆

        b[i]+=b[i-1]+a[i];

    }

    if(n==1){//特判,省得添堵

        printf("%d\n",a[n]);

        return 0;

    }

    for(k=1;k<=n-1;k++)

        for(i=1;i<=n;i++)

            if(i+k<=n)

                for(j=i;j<=i+k;j++)

                    f[i][i+k]=min(f[i][i+k],f[i][j]+f[j+1][i+k]+b[i+k]-b[i-1]);

    printf("%d\n",f[1][n]);

    return 0;

}

14.飛彈問題

//P1020 飛彈攔截

//NOIP 普及組 1999

//線上測評位址https://www.luogu.org/problemnew/show/P1020 

//開數組d[]存儲遞減序列 

//二分法,找目前資料放置d[]數組中位置。

//樣例通過,送出AC。2018-12-14 22:07

//算法時間複雜度,O(nlogn). 

#include <stdio.h>

int a[100100],d[100100];

int main(){

    int i,k=1,ans1=0,left,right,mid,ans2=0;

    while(scanf("%d",&a[k])!=EOF)k++;

    d[0]=60000;

    for(i=1;i<k;i++)//遞減序列處理 

        if(d[ans1]>=a[i])

            ans1++,d[ans1]=a[i];//d[]是遞減序列 

        else{

            left=0,right=ans1;

            while(left+1<right){

                mid=(left+right)/2;

                if(d[mid]>=a[i])left=mid;//此處寫成 if(d[ans1]>=a[i])left=mid;

                else right=mid;

            }

            d[right]=a[i];//目标,讓該遞減序列,每個位置的值都盡可能大 

        }

    printf("%d\n",ans1);

    d[0]=-1;

    for(i=1;i<k;i++)//嚴格遞增序列處理

        if(d[ans2]<a[i])

            ans2++,d[ans2]=a[i];

        else{

            left=0,right=ans2;

            while(left+1<right){

                mid=(left+right)/2;

                if(d[mid]<a[i])left=mid;

                else right=mid;

            }

            d[right]=a[i];//想清資料存儲格式,采用left還是right,自然明白 

        } 

    printf("%d\n",ans2);

    return 0;

}

//P1020 飛彈攔截

//NOIP 普及組 1999

//線上測評位址https://www.luogu.org/problemnew/show/P1020

//最長不上升子序列   飛彈個數

//最長上升降子序列   攔截系統套數

//樣例通過,送出WA,隻通過了測試點1.

//修改if(a[j]<a[i]&&d[j]+1>d[i])//計算攔截系統,此處寫成 if(a[j]<=a[i]&&d[j]+1>d[i])。

//送出,測試點1-10 AC,O(n^2)通過。2018-12-12 17:30

#include <stdio.h>

#include <string.h>

int a[100100],d[100100];

int max(int a,int b){

    return a>b?a:b;

}

int main(){

    int k=0,i,j,ans1=-1,ans2=-1;

    while(scanf("%d",&a[k])!=EOF)k++;

    for(i=0;i<k;i++){

        d[i]=1;

        for(j=0;j<i;j++)

            if(a[j]>=a[i]&&d[j]+1>d[i])

                d[i]=d[j]+1,ans1=max(ans1,d[i]);

    }

    for(i=0;i<k;i++){

        d[i]=1;

        for(j=0;j<i;j++)

            if(a[j]<a[i]&&d[j]+1>d[i])//計算攔截系統,此處寫成 if(a[j]<=a[i]&&d[j]+1>d[i])

                d[i]=d[j]+1,ans2=max(ans2,d[i]);

    }

    printf("%d\n%d\n",ans1,ans2);

    return 0;

}

15.均分紙牌

//P1031 均分紙牌

//NOIP 2002 提高組

//線上測評位址https://www.luogu.org/problemnew/show/P1031

//純模拟,由左往右開始填坑。

//很是高興,一次送出,就AC。沒有參考任何其它。2018-12-19

//樣例過程如下

9  8  17 6

10 7  17 6

10 10 14 6

10 10 10 10

#include <stdio.h>

#define maxn 110

int a[maxn];

int main(){

    int n,i,avg=0,cnt=0;

    scanf("%d",&n);

    for(i=1;i<=n;i++)

        scanf("%d",&a[i]),avg+=a[i];

    avg/=n;

    for(i=1;i<n;i++)

        if(a[i]!=avg)

            a[i+1]+=a[i]-avg,cnt++;//a[i]多移走,少補進

    printf("%d\n",cnt);

    return 0;

}

16.機器工廠

//P1376 機器工廠

//線上測評位址https://www.luogu.org/problemnew/show/P1376

//吐糟該題,看了半天沒看懂,出題人的第一要務,要讓人看懂題

//若無能力表述清楚,至少,應将給出的樣例解釋清楚。

//對樣例進行解釋

4 5         共4周 每周每台保管費5

88 200   第1周  每台費用88  需200台

89 400   第2周  每台費用89  需400台

97 300   第3周  每台費用97  需300台

91 500   第3周  每台費用91  需500台

該樣例資料計算

第1周 每台費用 88                       需200   花銷88*200

第2周 每台費用 93   89                需400   花銷89*400

第3周 每台費用 98   94  97          需300   花銷94*300

第4周 每台費用 103 99  102 91   需300   花銷91*300

                                                              總花銷126900

//有了基本算法,在一堆價格中,取最小值,進行計算

//采用O(n)的算法

//總花銷,最大值5000*10000=5*10^7 int不會溢出

//樣例通過,送出90分,測試點6 WA.

//翻看題解,表示,不服,怎麼會用到long long

//反複讀題,才發現,每周最多10000台,每台最多花費5000,最多10000周

//那麼最大值10000*5000*10000=5*10^11,現在同意用long long了

//long long cost=0;//之前寫成 int cost=0;交90分,測試點6 WA.

//修改,送出AC。2019-1-16

//大意失荊州,題目還是要多讀,最好還是要動紙筆。

#include <stdio.h>

#include <string.h>

#define maxn 10100

int n,s,a,b;//b該周的費用,a該周之前一周的費用

int min(int a,int b){

    return a<b?a:b;

}

int main(){

    int i,y;

    long long cost=0;//之前寫成 int cost=0;交90分,測試點6 WA.

    a=999999999;

    scanf("%d%d",&n,&s);

    for(i=1;i<=n;i++){

        scanf("%d%d",&b,&y);

        a=min(a+s,b);

        cost+=a*y;

    }

    printf("%lld\n",cost);

    return 0;

}

17.機器配置設定

//P2066 機器配置設定

//線上測評位址https://www.luogu.org/problemnew/show/P2066

//線上測評位址http://ybt.ssoier.cn:8088/problem_show.php?pid=1266

//在兩個線上測評網址之間切換,總算弄懂了題意。

//解釋樣例:

//公司1選3台 盈利50

//公司2選3台 盈利50

//公司3選3台 盈利30

//公司1選1台 盈利30 公司2選1台 盈利20 公司3選1台 盈利20 總共盈利 70

//f[i][j] i台機器 被 j個公司選 的最大盈利值

//列印 分公司編号和該分公司獲得裝置台數。沒什麼感覺

//那麼,将動歸的中間過程列印,找規律。

//發現

//f[1][1]=30,f[0][0]=0 i=1 j=1 k=1

//f[2][2]=50,f[1][1]=30 i=2 j=2 k=1

//f[3][3]=70,f[2][2]=50 i=3 j=3 k=1

//找到規律,以遞歸的方式列印結果。

//樣例通過,送出10分,測試點2-10WA。2019-1-15 17:07

//有多組解的情況處理,if(f[i][j]<=f[i-1][j-k]+a[i][k]){//此處寫成 if(f[i][j]<f[i-1][j-k]+a[i][k])

//送出20分,測試點3-10WA。2019-1-15 17:10

//翻看了之前的代碼https://blog.csdn.net/mrcrack/article/details/78440134

//發現for(k=0;k<=j;k++)//此處寫成for(k=1;k<=j;k++)

//就這一處差别,造成了 20分 與 100分 的差距。2019-1-15 17:16

//覺的又困惑,針對樣例,将for(k=0;k<=j;k++)的資料列印如下

f[1][1]=30 f[1][2]=40 f[1][3]=50

f[2][1]=30 f[2][2]=50 f[2][3]=60

f[3][1]=30 f[3][2]=50 f[3][3]=70

//将for(k=1;k<=j;k++)的資料列印如下

f[1][1]=30 f[1][2]=40 f[1][3]=50

f[2][1]=20 f[2][2]=50 f[2][3]=60

f[3][1]=20 f[3][2]=40 f[3][3]=70

//各位看到差别了嗎.2019-1-15 17:20

//該題編寫,還是比較滿意的,除了一處k=0還是k=1是翻看之前的編寫記錄,其它都是獨立編寫,且獨立改正的。2019-1-15 17:29

#include <stdio.h>

#include <string.h>

int a[15][20],f[15][20],g[15][20];

void print(int x,int y){//選擇了x個公司,選擇了y件機器

    if(x==0)return;

    print(x-1,y-g[x][y]);

    printf("%d %d\n",x,g[x][y]);

}

int main(){

    int n,m,i,j,k;

    memset(f,0,sizeof(f));

    scanf("%d%d",&n,&m);

    for(i=1;i<=n;i++)

        for(j=1;j<=m;j++)

            scanf("%d",&a[i][j]);

    for(i=1;i<=n;i++)

        for(j=1;j<=m;j++)

            for(k=0;k<=j;k++)//此處寫成for(k=1;k<=j;k++)//這是最關鍵的一行代碼

                if(f[i][j]<=f[i-1][j-k]+a[i][k]){//此處寫成 if(f[i][j]<f[i-1][j-k]+a[i][k])

                    f[i][j]=f[i-1][j-k]+a[i][k];

                    g[i][j]=k;//選擇了x個公司,選擇了y件機器 ,此次需加入的機器數量k

                }

    printf("%d\n",f[n][m]);

    print(n,m);

    return 0;

}

dfs

18.素數環

//Prime Ring Problem HDU - 1016

//線上測評位址https://vjudge.net/problem/HDU-1016

//回溯+深搜

//要點,頭尾兩數和為質數

//送出Wrong Answer,發現 k++,printf("\nCase %d:\n",k);//此處寫成 k++,printf("\nCase k:\n");

//送出Wrong Answer,估計 格式的 問題,繼續修改

//覺得格式修改無誤了,送出,竟然出現Presentation Error

//好歹知道現在出現的問題,就是格式問題。

//再讀題,發現這麼一句Print a blank line after each case.

//繼續修改,送出AC。2018-12-12 一度想要求助網絡,不過,還是忍住了,獨立AC。

//ACM的送出方式,對格式要求真高。

#include <stdio.h>

#include <string.h>

int vis[30],a[30],n,kase=0;

int isPrime(int x){//質數 傳回1 非質數 傳回0

    int i;

    if(x==1)return 0;

    if(x==2)return 1;

    for(i=2;i*i<=x;i++)

        if(x%i==0)return 0;

    return 1;

}

void dfs(int step){

    int i,k;

    if(step==n+1){

        if(n>=2&&isPrime(a[1]+a[n])){//此處寫成 if(isPrime(a[1]+a[n])

            printf("%d",a[1]);

            for(k=2;k<=n;k++)

                printf(" %d",a[k]);

            printf("\n");

        }

        return;

    }

    for(i=1;i<=n;i++)

        if(vis[i]==0&&isPrime(a[step-1]+i)){

            vis[i]=1,a[step]=i;

            dfs(step+1);

            vis[i]=0;

        }

}

int main(){

    while(scanf("%d",&n)!=EOF){

        memset(vis,0,sizeof(vis));

        kase++;

        printf("Case %d:\n",kase);//此處寫成 k++,printf("\nCase k:\n");

        a[1]=1,vis[1]=1;

        dfs(2);

        printf("\n");//少了此句

    }

    return 0;

}

模拟

19.黑色星期五

//P1202 [USACO1.1]黑色星期五Friday the Thirteenth

//線上測評位址https://www.luogu.org/problemnew/show/P1202 

//看了看該題,有點煩,編好該題,對日期的處理應是手到擒來。 

//閏年判定函數, 

//月天數數組。

//編完一個函數,或功能,測試是必需的。 

//思路,算出每個月13号,從1900年開始的天數,再進行星期幾的計算。

//樣例通過,送出AC。2018-12-9 17:00 

#include <stdio.h>

#include <string.h>

int month[]={0,31,28,31,30,31,30,31,31,30,31,30,31};//month[1]表示1月的天數 

int week[10];

int run(int year){//閏年傳回1,平年傳回0

    if(year%100==0)return year%400?0:1;//整百年        

    else return year%4?0:1;//非整百年

}

int main(){

    int n,i,j,year,tot=0,day=0;//tot當年開始之前的總天數。 day=0當年開始的總天數 

    memset(week,0,sizeof(week));//week[1]周一,week[6]周六,week[0]周日 

    scanf("%d",&n);

    for(i=0;i<n;i++){

        year=1900+i;

        month[2]=run(year)?29:28;

        if(i>0)tot+=(365+run(year-1));

        day=tot+13;

        for(j=0;j<12;j++){

            day+=month[j];

            week[day%7]++;

        }

    }

    printf("%d %d",week[6],week[0]);

    for(i=1;i<=5;i++)

        printf(" %d",week[i]);

    return 0;

20.單數?雙數?

//2163 單數??雙數????

//線上測評位址http://codevs.cn/problem/2163/

//該題,資料(1 <= I <= 10^60)看起來挺吓人 

//起始用字元串存儲,判斷最後一位是否奇偶即可

//樣例通過,送出AC。2018-12-9 21:18

#include <stdio.h>

#include <string.h>

char s[100];

int main(){

    int t,len;

    scanf("%d",&t);

    while(t--){

        scanf("%s",s);

        len=strlen(s);

        if((s[len-1]-'0')%2)printf("odd\n");

        else printf("even\n");

    }

    return 0;

2019-1-16 AC 該周内容