简单枚举
1.美丽的2(2020试题A(国赛))
思路:枚举1到2020,把每个数位拿出来看是否有2,有就ans++同时跳过这个数,没有就不管,最后输出ans。
#include<stdio.h>
int check(int n)
{
int flag=0;
while(n)
{
int m=n%10;
if(m==2)
{
flag=1;
break;
}
n/=10;
}
return flag;
}
int main()
{
int ans=0;
for(int i=1;i<=2020;i++)
{
if(check(i))
ans++;
}
printf("%d",ans);
return 0;
}
2 .门牌制作(2020第二场试题A)
思路:同上题差不多,区别就是要把break去掉。
#include<stdio.h>
int check(int n)
{
int count=0;
while(n)
{
int m=n%10;
if(m==2)
count++;
n/=10;
}
return count;
}
int main()
{
int ans=0;
for(int i=1;i<=2020;i++)
ans+=check(i);
printf("%d",ans);
return 0;
}
3.既约分数(2020第二场试题B)
思路:枚举分子分母,判断每次最大公约数是不是为1。
#include<stdio.h>
int gcd(int a,int b)
{
if(a<b)
{
int t=a;a=b;b=t;
}
while(b)
{
int T=a%b;
a=b;
b=T;
}
return a;
}
int main()
{
int ans=0;
for(int i=1;i<=2020;i++)
for(int j=1;j<=2020;j++)
{
if(gcd(i,j)==1)
ans++;
}
printf("%d",ans);
return 0;
}
4.蛇形填数 (2020第二场试题C)![](https://img-blog.csdnimg.cn/31d34b83db0a42f3897d34c7100a50dd.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAcXFfMTM1MTkzNDY2Nw==,size_19,color_FFFFFF,t_70,g_se,x_16)
思路:找规律
aij=1+2+...+(i+j-2)+(i(i+j为奇数)||j(i+j为偶数))
5.卡片(2021试题B)![](https://img-blog.csdnimg.cn/b189f9294f374b01bef1bb0618bbddeb.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAcXFfMTM1MTkzNDY2Nw==,size_19,color_FFFFFF,t_70,g_se,x_16)
思路:开一个数组存放0到9,令这个数组0到9都等于2021,从1开始累加,处理每个数的每一位,令该数位在对应数组的值自减,直至最后数组等于0。
#include<stdio.h>
int a[10]={2021,2021,2021,2021,2021,2021,2021,2021,2021,2021};
int check(int j)
{
while(j)
{
a[j%10]--;
if(a[j%10]<0)
return 0;
j/=10;
}
return 1;
}
int main()
{
int i;
for(i=1;;i++)
{
if(check(i)==0)
break;
}
printf("%d",i-1);
return 0;
}
6.直线(2021试题C)
思路,首先可以确定垂直于x轴,y轴的直线各有20,21条。再确定剩下的直线,一条直线可以确定他的斜率和截距,通过这两条可以筛出相同的直线。
注意:精度问题。
#include<stdio.h>
int count=0;
struct Line
{
double k;
double b;
}L[100000];
int check(double k,double b)
{
for(int i=0;i<count;i++)
{
if(L[i].k==k&&L[i].b==b)
return 0;
}
return 1;
}
int main()
{
for(int x1=0;x1<=19;x1++)
for(int x2=0;x2<=19;x2++)
if(x1!=x2)
for(int y1=0;y1<=20;y1++)
for(int y2=0;y2<=20;y2++)
if(y1!=y2)
{
double k=(y2-y1)*1.0/(x2-x1);
double b=(y2*(x2-x1)-(y2-y1)*x2)*1.0/(x2-x1);
if(check(k,b))
{
L[count].k=k;
L[count].b=b;
count++;
}
}
printf("%d",count+20+21);
return 0;
}
7.货物摆放(2021试题D)
思路,将n的所有因子存入一个数组,三层枚举数组,看相乘是否为n。
#include<stdio.h>
long long a[10000];
int main()
{
long long n=2021041820210418,count=0,ans=0;
for(long long i=1;i*i<=n;i++)
{
if(n%i==0)
{
a[count++]=i;
if(n/i!=i)
a[count++]=n/i;
}
}
for(int x=0;x<count;x++)
for(int y=0;y<count;y++)
for(int z=0;z<count;z++)
if(a[x]*a[y]*a[z]==n)
ans++;
printf("%lld",ans);
return 0;
}
枚举排列
1.六角填数(2014第七题)
#include<stdio.h>
#include<algorithm>
using namespace std;
int a[9]={2,4,5,6,7,9,10,11,12};
int check()
{
int t[6];
t[0]=1+a[0]+a[3]+a[5];
t[1]=1+a[1]+a[4]+a[8];
t[2]=a[5]+a[6]+a[7]+a[8];
t[3]=8+a[0]+a[1]+a[2];
t[4]=8+3+a[3]+a[6];
t[5]=3+a[2]+a[4]+a[7];
for(int i=1;i<6;i++)
{
if(t[i]!=t[i-1])
return 0;
}
return 1;
}
int main()
{
do
{
if(check())
printf("%d",a[3]);
}while(next_permutation(a,a+9));
return 0;
}
2.凑算式 (2016第三题)
A到I为1到9,求有多少种取法?
注意:除法时,要乘上1.0
#include<stdio.h>
#include<algorithm>
using namespace std;
int a[9]={1,2,3,4,5,6,7,8,9};
int check()
{
if(a[0]+a[1]*1.0/a[2]+(a[3]*100+a[4]*10+a[5])*1.0/(a[6]*100+a[7]*10+a[8])*1.0==10)
return 1;
return 0;
}
int main()
{
int ans=0;
do
{
if(check())
ans++;
}while(next_permutation(a,a+9));
printf("%d",ans);
return 0;
}
3.方格填数 (2016第六题)
#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
int b[10][10]={
{0,1,0,1,1,1,0,0,0,0},
{1,0,1,0,1,1,1,0,0,0},
{0,1,0,0,0,1,1,0,0,0},
{1,0,0,0,1,0,0,1,1,0},
{1,1,0,1,0,1,0,1,1,1},
{1,1,1,0,1,0,1,0,1,1},
{0,1,1,0,0,1,0,0,0,1},
{0,0,0,1,1,0,0,0,1,0},
{0,0,0,1,1,1,0,1,0,1},
{0,0,0,0,1,1,1,0,1,0},
};
int a[10]={0,1,2,3,4,5,6,7,8,9};
int check(int i)
{
for(int k=0;k<i;k++)
if((b[i][k]==1)&&(fabs(a[i]-a[k])==1))
return 0;
return 1;
}
int main()
{
int ans=0,i;
do
{
for(i=0;i<10&&check(i);i++);
if(i>=10)
ans++;
}while(next_permutation(a,a+10));
printf("%d",ans);
return 0;
}