第十二届蓝桥杯大赛软件赛省赛
作者:互联网
试题A:卡片
题解
#include<bits/stdc++.h>
using namespace std;
int a[10];
bool check(int x){
while(x){
int t=x%10;
if(!a[t])return false;
--a[t];
x/=10;
}
return true;
}
int main(){
for(int i=0;i<10;++i)a[i]=2021;
int ans=0;
while(1){
++ans;
if(!check(ans))break;
}
cout<<ans-1;
return 0;
}
答案:3181
试题B:直线
题解
法一
手动设置精度,小于该精度即认为相等
#include<bits/stdc++.h>
using namespace std;
#define db double
struct no{
int x,y;
no(int a,int b):x(a),y(b){}
};
db eps=1e-6;
vector<no>point;
vector<pair<db,db>>ans;
int main(){
for(int i=0;i<20;++i)
for(int j=0;j<21;++j){
point.push_back(no(i,j));
}
int tot=point.size();
for(int i=0;i<tot;++i)
for(int j=i+1;j<tot;++j){
db x1=point[i].x,y1=point[i].y;
db x2=point[j].x,y2=point[j].y;
if(x1==x2||y1==y2)continue;
db k=(y1-y2)/(x1-x2);
db b=y1-k*x1;
int flag=1;
for(int c=0;c<ans.size();++c){
if(fabs(k-ans[c].first)<eps&&fabs(b-ans[c].second)<eps){
flag=0;break;
}
}
if(flag)ans.push_back(make_pair(k,b));
}
cout<<ans.size()+20+21;
return 0;
}
法二
修改b的表达式:\(b=\frac{y_2*x_1-y_1*x_2}{x_1-x_2}\),就像\(\frac{2}{3} = \frac{4}{6}\)防止误差产生。
#include<bits/stdc++.h>
using namespace std;
#define db double
struct no{
int x,y;
no(int a,int b):x(a),y(b){}
};
db eps=1e-6;
vector<no>point;
set<pair<db,db>>ans;
int main(){
for(int i=0;i<20;++i)
for(int j=0;j<21;++j){
point.push_back(no(i,j));
}
int tot=point.size();
for(int i=0;i<tot;++i)
for(int j=i+1;j<tot;++j){
db x1=point[i].x,y1=point[i].y;
db x2=point[j].x,y2=point[j].y;
if(x1==x2||y1==y2)continue;
db k=(y1-y2)/(x1-x2);
db b=(y2*x1-y1*x2)/(x1-x2);
int flag=1;
ans.insert({k,b});
}
cout<<ans.size()+20+21;
return 0;
}
答案:40257
试题C:货物摆放
题解
数字超级大,但质因数只有8个,因数只有128个,暴力枚举即可
顺便说一下因数个数等于不同质因数的指数分别加1后相乘的积
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=2021041820210418;
//const ll N=4;
ll prime[100],cntp;
set<ll>factor;
void get_p(){
ll x=N;
for(int i=2;i*i<=x;++i){
while(x%i==0)prime[cntp++]=i,x/=i;
}
if(x)prime[cntp++]=x;//分解质因数
}
void dfs(int p,int n,int tot,ll num){//p当前位置,n已选个数,tot总长度
if(tot==n){
factor.insert(num);
return ;
}
for(int i=p;i<cntp;++i){
dfs(i+1,n+1,tot,num*prime[i]);
dfs(i+1,n,tot,num);
}
return ;
}
int main(){
get_p();
cout<<"质因数个数:"<<cntp<<endl;
for(int i=0;i<cntp;++i)cout<<prime[i]<<" ";
factor.insert(1);
for(int len=1;len<=cntp;++len){
dfs(0,0,len,1);//找因数
}
cout<<endl<<"因数个数:"<<factor.size();
int ans=0;
for(auto i:factor)//开始暴力枚举
for(auto j:factor)
for(auto k:factor){
if(i*j*k==N)++ans;
}
cout<<endl<<"答案:"<<ans;
return 0;
}
答案:
试题D:路径
题解
求最短路常用的三种方法:
1.弗洛伊德(Floyd-Warshall algorithm)多源最短路
2.spfa(贝尔曼福特(Bellman-Ford)的队列优化)单源最短
3.迪杰斯特拉(Dijkstra)单源最短
这里贴一个dijkstra
#include<bits/stdc++.h>
using namespace std;
const int N=2050;
struct no{
int x,id;
no(int a,int b):id(a),x(b){}
no(){}
const bool operator<(const no&a)const{
return x>a.x;//与小根堆配套使用
}
};
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
int g[N][N],dis[N],book[N];
priority_queue<no>q;
void dij(){
dis[1]=0;
q.push(no(1,0));
while(q.size()){
no now=q.top();
q.pop();
if(book[now.id])continue;
book[now.id]=1;
for(int i=1;i<=2021;++i){
if(dis[i]>dis[now.id]+g[now.id][i]){
dis[i]=dis[now.id]+g[now.id][i];
q.push(no(i,dis[i]));
}
}
}
}
int main(){
memset(dis,0x3f,sizeof(dis));
memset(g,0x3f,sizeof(g));
for(int i=1;i<=2021;++i)
for(int j=i+1;j<=i+21;++j){
g[i][j]=i*j/gcd(i,j);
g[j][i]=g[i][j];
}
dij();
cout<<dis[2021];
return 0;
}
答案:10266837
试题E:回路计数
题解
状压 dp 是动态规划的一种,通过将状态压缩为整数来达到优化转移的目的。 ---OI Wiki
状态压缩的思想是用二进制来表示状态。用一个整数的二进制形式的每一个0或1表示一个状态。
f[i][j]表示当前处在点i状态为j
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=21;
const int M=1<<N;
int g[N][N];
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
ll f[N][M];
int main(){
for(int i=0;i<N;++i)
for(int j=i+1;j<N;++j){
if(gcd(i+1,j+1)==1)g[i][j]=g[j][i]=1;
}
f[0][1]=1;
for(int i=2;i<M;++i)//从小到大遍历每一种状态
for(int j=0;j<N;++j){
if((i&(1<<j))==0)continue;
for(int k=0;k<N;++k){
if((i&(1<<k))==0||j==k)continue;
if(g[j][k]) f[j][i]+=f[k][i-(1<<j)];
}
}
ll ans=0;
for(int i=1;i<N;++i)ans+=f[i][M-1];
cout<<ans;
return 0;
}
注意==优先级高于&
答案:881012367360
剩下的明天再写
标签:const,no,赛省赛,第十二届,蓝桥,int,now,id,dis 来源: https://www.cnblogs.com/hetailang/p/15852058.html