1. 程式人生 > >第六屆藍橋杯題解

第六屆藍橋杯題解

1、獎券數目

法一:

#include<stdio.h>  
int main()  
{  
    int ans=0;  
    for(int i=1; i<=9; i++)  
        for(int j=0; j<=9; j++)  
            for(int k=0; k<=9; k++)  
                for(int l=0; l<=9; l++)  
                    for(int s=0; s<=9; s++)  
                        if(i!=4&&j!=4&&k!=4&&l!=4&&s!=4)  
                            ans++;  
    printf("%d\n",ans);  
    return 0;  
}  
法二:

//第六屆藍橋杯第一題  獎券數目
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 0x3f3f3f3f;

int dp[10][10];

void find_dp()
{
    dp[0][0] = 1;
    for(int i = 1 ; i <= 9 ; i++){
        for(int j = 0 ; j <= 9 ; j++){
            if(j == 4) dp[i][j] = 0;
            else{
                for(int k = 0 ; k <= 9 ; k++)
                    dp[i][j] += dp[i-1][k];
            }
        }
    }
}


int a[10];
int fun(int n)
{
    a[0]=0;
    while (n)
    {
        a[++a[0]]=n%10;
        n/=10;
    }
    int ans = 0;   //a[0]放的就是長度

    for(int i = a[0] ; i >= 1 ; i--){//現在還有幾位數
        for(int j = 0 ; j < a[i] ; j++){//從誰開頭
            if(j != 4)
                ans += dp[i][j];
            else break;
        }
    }
    return ans;
}

int main()
{
    int n, m;
    int i, j;
    int a[10];
    int b[10];

    find_dp();
    while(cin >> n >> m){
        cout << fun(m+1) - fun(n) << endl;
    }
    return 0;
}

3.三羊獻瑞

//藍橋杯第六屆第三題 三羊獻瑞
//不可重複排列組合問題
#include <iostream>
#include <cstdio>
#include <cstring>


using namespace std;


typedef long long LL;//視情況定型別


const int maxn = 0x3f3f3f3f;
int a[15];
int ans[15], vis[15];
int n;


int is_true()
{
	int x, y, z;


	x=ans[0]*1000+ans[1]*100+ans[2]*10+ans[3];
        y=ans[4]*1000+ans[5]*100+ans[6]*10+ans[1];
        z=ans[4]*10000+ans[5]*1000+ans[2]*100+ans[1]*10+ans[7];
    
	if(x + y == z)
		return 1;
	return 0;
}


void dfs(int t)
{
	if(t == n){
		if(is_true() == 1){
			printf("%d %d %d %d\n", ans[4], ans[5], ans[6], ans[1]);
		}
		else return ;
	}
	else{
		for(int i = 0 ; i < 10 ; i++){
            if(t==0&&i==0)
            continue;
            if(t==4&&i!=1)
            continue;//以上四行表示首位不能為0


			if(!vis[i]){
				ans[t] = a[i];
				vis[i] = 1;
				dfs(t+1);
				vis[i] = 0;
			}
		}
	}
}


int main()
{
	cin >> n;
	memset(ans, 0, sizeof(ans));
	for(int i = 0 ; i < 10 ; i++)
		a[i] = i;
	dfs(0);
}

4.格子中輸出

#include <stdio.h>
#include <string.h>

void StringInGrid(int width, int height, const char* s)
{
    int i,k;
    char buf[1000];
    strcpy(buf, s);
    if(strlen(s)>width-2) buf[width-2]=0;

    printf("+");
    for(i=0;i<width-2;i++) printf("-");
    printf("+\n");

    for(k=1; k<(height-1)/2;k++){
        printf("|");
        for(i=0;i<width-2;i++) printf(" ");
        printf("|\n");
    }

    printf("|");

    printf("%*s%s%*s",(width-strlen(s)-2)/2,"",s,(width-strlen(s)-2)/2,""  );  //填空

    printf("|\n");

    for(k=(height-1)/2+1; k<height-1; k++){
        printf("|");
        for(i=0;i<width-2;i++) printf(" ");
        printf("|\n");
    }

    printf("+");
    for(i=0;i<width-2;i++) printf("-");
    printf("+\n");
}

int main()
{
    StringInGrid(20,6,"abcd1234");
    return 0;
}


5.九陣列分數

#include <stdio.h>  
  
void test(int x[])  
{  
    int a = x[0]*1000 + x[1]*100 + x[2]*10 + x[3];  
    int b = x[4]*10000 + x[5]*1000 + x[6]*100 + x[7]*10 + x[8];  
  
    if(a*3==b) printf("%d / %d\n", a, b);  
}  
  
void f(int x[], int k)  
{  
    int i,t;  
    if(k>=9)  
    {  
        test(x);  
        return;  
    }  
  
    for(i=k; i<9; i++)  
    {  
        {  
            t=x[k];  
            x[k]=x[i];  
            x[i]=t;  
        }  
        f(x,k+1);  
        {  
            t=x[k];    // 填空處  
            x[k]=x[i];  
            x[i]=t;  
        }  
    }  
}  
  
int main()  
{  
    int x[] = {1,2,3,4,5,6,7,8,9};  
    f(x,0);  
    return 0;  
}  


6.加法變乘法

#include<string.h>
#include<stdio.h>
#include<iostream>
#include<math.h>
using namespace std;
int main()
{
    int a,b;
    for(a=1;a<=48;a++)
    {
        for(b=a+1;b<=48;b++)
        {
            if(1225-a-(a+1)-b-(b+1)+a*(a+1)+b*(b+1)==2015)//如果1225減去變化的加,加上變後的乘等於2015即可
            {
                printf("%d %d\n",a,b);
            }
        }
    }
    return 0;
}
7.牌型種數

//不可重複排列組合問題
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;
const int maxn = 0x3f3f3f3f;

int ans = 0;

void dfs(int cur,int sum)  //cur 當前的層數 相當於選了幾次牌, sum 現在在手中的總的牌數

{
    if(sum > 13)  //手中的牌數太多了
        return;  
    if(cur == 13){  //保證每個(1 2 3 ... 13)牌都選過了
        if(sum == 13){  //保證手中只有13個牌
            ans++;  
        } 
        return;  
    }
    for(int i = 0; i <= 4; i++)  
        dfs(cur+1, sum+i);  
}  
  
int main()  
{
    dfs(0,0);
    printf("%d\n",ans); 
	system("pause");
    return 0;
}
		
8.移動距離

#include<stdio.h>  
#include<cmath>  
using namespace std;  
int main()  
{  
    int w,m,n;  
    scanf("%d%d%d",&w,&m,&n);  
    int x1,x2,y1,y2;  
    x1=(m-1)/w;  
    y1=(m-1)%w;  
    x2=(n-1)/w;  
    y2=(n-1)%w;  
    if(x1%2)  
        y1=w-y1-1;  
    if(x2%2)  
        y2=w-y2-1;  
    printf("%d\n",abs(x1-x2)+abs(y1-y2));  
    return 0;  
}
9.壘骰子

#include<iostream>  
#include<cstdio>  
#include<cstring>  
#include<cmath>  
#include<algorithm>  
#include<vector>  
#include<queue>  
#include<map>  
#define LL long long  
#define MAXN 1000010  
using namespace std;  
const int INF=0x3f3f3f3f;  
//----以下為矩陣快速冪模板-----//   
//const int mod=3;//模3,故這裡改為3即可   
int mod;  
const int NUM=12;//定義矩陣能表示的最大維數   
int N;//N表示矩陣的維數,以下的矩陣加法、乘法、快速冪都是按N維矩陣運算的   
struct Mat{//矩陣的類  
    LL a[NUM][NUM];  
    void init()//將其初始化為單位矩陣    
    {  
        memset(a,0,sizeof(a));  
        for(int i=0;i<NUM;i++)  
        {  
            a[i][i]=1;  
        }  
    }  
};  
Mat add(Mat a,Mat b)//(a+b)%mod  矩陣加法    
{  
    Mat ans;  
    for(int i=0;i<N;i++)  
    {  
        for(int j=0;j<N;j++)  
        {  
            ans.a[i][j]=(a.a[i][j]%mod)+(b.a[i][j]%mod);  
            ans.a[i][j]%=mod;  
        }  
    }  
    return ans;  
}  
Mat mul(Mat a,Mat b) //(a*b)%mod  矩陣乘法    
{  
    Mat ans;  
    for(int i=0;i<N;i++)  
    {  
        for(int j=0;j<N;j++)  
        {  
            ans.a[i][j]=0;  
            for(int k=0;k<N;k++)  
            {  
                ans.a[i][j]=(ans.a[i][j]%mod)+(a.a[i][k]%mod)*(b.a[k][j]%mod);  
            }  
            ans.a[i][j]%=mod;  
        }  
    }  
    return ans;  
}  
Mat power(Mat a,int num)//(a^n)%mod  矩陣快速冪   
{  
    Mat ans;  
    ans.init();  
    while(num)  
    {  
        if(num&1)  
        {  
            ans=mul(ans,a);  
        }  
        num>>=1;  
        a=mul(a,a);  
    }  
    return ans;  
}  
Mat pow_sum(Mat a,int num)//(a+a^2+a^3....+a^n)%mod 矩陣的冪和  
{  
    int m;  
    Mat ans,pre;  
    if(num==1)  
        return a;  
    m=num/2;  
    pre=pow_sum(a,m);  
    ans=add(pre,mul(pre,power(a,m)));  
    if(num&1)  
        ans=add(ans,power(a,num));  
    return ans;  
}  
void output(Mat a)//輸出矩陣   
{  
    for(int i=0;i<N;i++)  
    {  
        for(int j=0;j<N;j++)  
        {  
            printf("%lld%c",a.a[i][j],j==N-1?'\n':' ');  
        }  
    }  
}  
//----以上為矩陣快速冪模板-----//   
  
int v[6][6];  
int main()  
{  
    Mat A,B;  
    int i,j,k,n,m,x,y,sum;  
    while(scanf("%d%d",&n,&m)!=EOF)  
    {  
        for(i=0;i<6;i++)  
        {  
            for(j=0;j<6;j++)  
            {  
                v[i][j]=1;    
            }     
        }  
        for(i=1;i<=m;i++)      
        {  
            scanf("%d%d",&x,&y);  
            v[x-1][(y+2)%6]=0;  
            v[y-1][(x+2)%6]=0;  
        }  
        N=6;  
        mod=1e9+7;  
        for(i=0;i<6;i++)  
        {  
            for(j=0;j<6;j++)  
            {  
                A.a[i][j]=v[i][j]*4;  
            }  
        }  
        for(i=0;i<6;i++)  
            B.a[i][0]=4;  
        A=power(A,n-1);  
        Mat ans;  
        for(i=0;i<N;i++)  
        {  
            for(j=0;j<1;j++)  
            {  
                ans.a[i][j]=0;  
                for(k=0;k<N;k++)  
                {  
                    ans.a[i][j]=(ans.a[i][j]%mod)+(A.a[i][k]%mod)*(B.a[k][j]%mod);  
                }  
                ans.a[i][j]%=mod;  
            }  
        }  
        sum=0;  
        for(i=0;i<N;i++)  
        {  
            sum=(sum+ans.a[i][0])%mod;  
        }  
        printf("%d\n",sum);  
    }  
    return 0;  
}  
  
10.生命之樹

#include<string.h>  
#include<stdio.h>  
#include<iostream>  
#include<math.h>  
#define LL long long  
#define MAXN 1000010  
#define INF 0x3f3f3f3f  
using namespace std;  
  
struct node{  
    int from;  
    int to;  
    int w;  
    int next;  
}Edge[MAXN];  
  
int n,m,tot;  
int head[MAXN],dp[MAXN][2],w[MAXN];  
void init()  
{  
    memset(head,-1,sizeof(head));  
    tot=0;  
}  
void add(int from,int to,int w)  
{  
    Edge[tot].from=from;  
    Edge[tot].to=to;  
    Edge[tot].w=w;  
    Edge[tot].next=head[from];  
    head[from]=tot++;  
}  
  
void dfs(int p,int fa)  
{  
    for(int i=head[p];i!=-1;i=Edge[i].next)  
    {  
        int v=Edge[i].to;  
        if(v==fa)  
            continue;  
        dfs(v,p);  
        dp[p][0]=max(dp[v][0],dp[v][1]);  
        dp[p][1]=max(dp[v][1]+dp[p][1],dp[p][1]);  
    }  
}  
  
int main()  
{  
    int i,j,u,v,ans;  
    while(scanf("%d",&n)!=EOF)  
    {  
        memset(dp,-INF,sizeof(dp));  
        for(i=1;i<=n;i++)  
        {  
            scanf("%d",&w[i]);  
            dp[i][1]=w[i];  
        }  
        init();  
        for(i=1;i<=n-1;i++)  
        {  
            scanf("%d%d",&u,&v);  
            add(u,v,0);  
            add(v,u,0);  
        }  
        dfs(1,-1);  
        ans=max(dp[1][0],dp[1][1]);  
        printf("%d\n",ans);  
    }  
    return 0;  
}