第六屆藍橋杯題解
阿新 • • 發佈:2018-12-07
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;
}
#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;
}