目录
前言
本文收录2023年《程序设计与算法基础》(原名计算智能)课程的课后作业(即考试范围)的所有算法题和其中一种题解,仅供笔者本人及同学们方便复习参考。由于笔者本人水平有限,本文代码部分原创,整合搬运多方代码,仅供参考。
考试时采用抽题方式共八题,其中必选题四道各15分,二选一题两道各15分,创新题两道各5分
1 {18104,18118,18107,19121} 必选
18104 练习使用多case解题
18118 勇者斗恶龙
18107校赛排名
19121 小明手上的牌
2 {18440,19116,18005,18105} 必选
18440走迷宫2
19116 丑教
18005它不是丑数
18105银行的叫号顺序
3 {1142,18441,18442,18443,8623,18124} 必选
1142巡逻的士兵
18441 偷懒的士兵
18442偷懒的士兵2
18443 除法等式
8623 龙龙
18124 N皇后问题
4 {18308,8615} 必选
18308最长公共子序列
8615快乐
5 {18276,18290,1079,18444} 任选其一
18276走迷宫
18290 校赛排名2
1079三角形
18444分数拆分
6 {19010,18233,18130} 任选其一
19010最小特殊教字
18233 万湖之国的形成
18130繁忙的公路
7 {19176} 自主出题
8 {19175} 自主出题
18104 练习使用多case解题
#include <iostream>
using namespace std;
int main()
{
int n;
long long a,b;
cin>>n;
while(n--)
{
cin>>a>>b;
for(int i=1;; i++)
{
if(a*i%b==0)
{
cout<<a*i<<endl;
break;
}
}
}
cout<<"group 1 done"<<endl;
while(cin>>a>>b &&(a!=0&&b!=0))
{
for(int i=1;; i++)
{
if(a*i%b==0)
{
cout<<a*i<<endl;
break;
}
}
}
cout<<"group 2 done"<<endl;
while(cin>>a>>b &&a!=EOF)
{
for(int i=1;; i++)
{
if(a*i%b==0)
{
cout<<a*i<<endl;
break;
}
}
}
cout<<"group 3 done"<<endl;
return 0;
}
18276 走迷宫
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair <int,int> P;
typedef struct
{
int endx,endy;
} NODE;
int main()
{
int T;
cin>>T;
while(T--)
{
int n,m;
cin>>n>>m;
char Map[105][105];
int step[105][105];
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
cin>>Map[i][j];
step[i][j]=-1;
}
}
int w;
cin>>w;
int c1,r1,c2,r2;
NODE Map2[105][105];
for(int i=0; i<w; i++)
{
cin>>c1>>r1>>c2>>r2;
Map2[c1][r1].endx=c2;
Map2[c1][r1].endy=r2;
Map[c1][r1]='2';
}
int sc,sr,ec,er;
cin>>sc>>sr>>ec>>er;
step[sc][sr]=0;
queue <P> q;
q.push({sc,sr});
while(!q.empty())
{
P t=q.front();
q.pop();
if(t.first==ec&&t.second==er)
{
break;
}
if(Map[t.first][t.second]=='2')
{
q.push({Map2[t.first][t.second].endx,Map2[t.first][t.second].endy});
step[Map2[t.first][t.second].endx][Map2[t.first][t.second].endy]=step[t.first][t.second]+1;
}
else
{
int dx[4]= {0,0,1,-1},dy[4]= {1,-1,0,0};
for(int i=0; i<4; i++)
{
int x=t.first+dx[i],y=t.second+dy[i];
if(x>=0&&y>=0&&x<n&&y<m&&Map[x][y]!='1'&&step[x][y]==-1)
{
q.push({x,y});
step[x][y]=step[t.first][t.second]+1;
}
}
}
}
if(step[ec][er]==-1) cout<<"die"<<endl;
else cout<<step[ec][er]<<endl;
}
return 0;
}
18440 走迷宫2
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair <int,int> P;
int main()
{
int T;
cin>>T;
while(T--)
{
int n,m;
cin>>n>>m;
char Map[105][105];
int step[105][105];
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
cin>>Map[i][j];
step[i][j]=-1;
}
}
int sc,sr,ec,er;
cin>>sc>>sr>>ec>>er;
step[sc][sr]=0;
queue <P> q;
q.push({sc,sr});
while(!q.empty())
{
P t=q.front();
q.pop();
if(t.first==ec&&t.second==er)
{
break;
}
else
{
int dx[4]= {0,0,1,-1},dy[4]= {1,-1,0,0};
for(int i=0; i<4; i++)
{
int x=t.first+dx[i],y=t.second+dy[i];
if(x<0) x=n-1;
if(x>=n) x=0;
if(y<0) y=m-1;
if(y>=m) y=0;
if(Map[x][y]!='1'&&step[x][y]==-1)
{
q.push({x,y});
step[x][y]=step[t.first][t.second]+1;
}
}
}
}
if(step[ec][er]==-1) cout<<"die"<<endl;
else cout<<step[ec][er]<<endl;
}
return 0;
}
19116 丑数
#include <iostream>
using namespace std;
int main()
{
int ugly[3000];
int a=1,b=1,c=1;
ugly[1]=1;
for(int i=2;i<3000;i++)
{
ugly[i]=min(ugly[a]*2,min(ugly[b]*3,ugly[c]*5));
if(ugly[i]==ugly[a]*2) a++;
if(ugly[i]==ugly[b]*3) b++;
if(ugly[i]==ugly[c]*5) c++;
}
int T,n;
cin>>T;
while(T--)
{
cin>>n;
cout<<ugly[n]<<endl;
}
return 0;
}
18005 它不是丑数
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
long long ugly[3000]={1};
int i=1;
int a=0,b=0,c=0;
while(i<3000)
{
ugly[i]=min(2*ugly[a],min(3*ugly[b],5*ugly[c]));
if(ugly[i]==2*ugly[a]) a++;
if(ugly[i]==3*ugly[b]) b++;
if(ugly[i]==5*ugly[c]) c++;
i++;
}
int T,n;
cin>>T;
while(T--)
{
cin>>n;
int coun=0;
int i=0;
while(coun<n)
{
coun+=ugly[i+1]-ugly[i]-1;
i++;
}
i--;
coun-=(ugly[i+1]-ugly[i]-1);
cout<<ugly[i]+(n-coun)<<endl;
}
return 0;
}
19121 小明手上的牌
#include <iostream>
using namespace std;
int main()
{
int n,m,i,goal=0;
int b[100005];
cin>>n>>m;
for(i=0; i<n; i++)
cin>>b[i];
for(i=0; i<m; i++) //判断最后一张是否为最大的m张
{
if(b[n-1]<n-i) goal++;
}
if(goal==m)
cout<<b[n-1];
else
cout<<n-m+1;
}
18105 银行的叫号顺序
#include<iostream>
#include<algorithm>
#include<queue>
#include<string>
using namespace std;
typedef pair<int,string> man;
priority_queue <man> q;
int main()
{
int ret=99999,realtime=0;
int time,level;
string name;
int n;
cin>>n;
while(n--)
{
cin>>time>>level>>name;
while(1)
{
if(time<=realtime)
{
q.push(make_pair(level*100000+ret,name));
ret--;
break;
}
if(!q.empty())
{
cout<<q.top().second<<endl;
q.pop();
}
realtime+=5;
}
}
while(!q.empty())
{
cout<<q.top().second<<endl;
q.pop();
}
return 0;
}
18118 勇者斗恶龙
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n,m,cost=0;
int head[200005],power[200005];
while(scanf("%d%d",&n,&m)&&(m!=0&&n!=0))
{
for(int i=0;i<n;i++)
{
cin>>head[i];
}
sort(head,head+n);
for(int i=0;i<m;i++)
{
cin>>power[i];
}
sort(power,power+m);
int i=0,j=0;
while(1)
{
if(head[i]<=power[j])
{
cost+=power[j];
i++;
j++;
}
else
j++;
if(i==n)
{
cout<<cost<<endl;
break;
}
if(j==m)
{
printf("Loowater is doomed!\n");
break;
}
}
}
return 0;
}
18107 校赛排名
#include <iostream>
#include <algorithm>
using namespace std;
typedef struct
{
char name[20];
int coun;
int t;
int value;
}player;
player a[500005];
bool cmp(player a,player b)
{
if(a.coun!=b.coun) return a.coun>b.coun;
if(a.t==b.t) return a.value<b.value;
return a.t<b.t;
}
int main()
{
int N;
scanf("%d",&N);
int i;
for(i=0;i<N;i++)
{
cin>>a[i].coun>>a[i].t>>a[i].name;
a[i].value=i;
}
sort(a,a+N,cmp);
for(i=0;i<N;i++)
{
printf("%s\n",a[i].name);
}
return 0;
}
18290 校赛排名2
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
struct STU
{
int time=0;
int pass=0;
char name[21];
int acname[20];
int fal[20];
};
struct STU stu[100000];
bool cmp(struct STU a,struct STU b)
{
if(a.pass==b.pass)
{
return a.time<b.time;
}
else return a.pass>b.pass;
}
int main()
{
int n=0,j,i,k=0,t,ifpass,mins;
char curname[21],title;
while(scanf("%d %s %c %d",&mins,curname,&title,&ifpass)!=EOF)
{
t=0;
for(i=0; i<=n-1; i++)
{
if(!strcmp(curname,stu[i].name))
{
t=1;
break;
}
}
if(!t)//如果t=0即这个队伍第一次露头
{
strcpy(stu[n].name,curname);
i=n;//i指向这只新队伍,否则用之前找到重名的对应的i
memset(stu[i].acname,0,sizeof(stu[i].acname));
memset(stu[i].fal,0,sizeof(stu[i].fal));
}
if(!ifpass&&stu[i].acname[title-65]!=1)//通过而且不是之前ac过的题
{
stu[i].pass++;//ac题数加一
stu[i].acname[title-65]=1;//标记为已通过
stu[i].time+=stu[i].fal[title-65]*20+mins;//之前这一题的罚时加上通过的当前时间
}
else if(ifpass)//没ac
{
stu[i].fal[title-65]++;
}
n++;
}
sort(stu,stu+n-1,cmp);
for(i=0; i<=n-1; i++)
{
if(stu[i].pass) printf("%s %d %d\n",stu[i].name,stu[i].pass,stu[i].time);
else break;
}
return 0;
}
1142 巡逻的士兵
#include <iostream>
#include <map>
using namespace std;
int F(int n)
{
if(n<3) return 0;
else if(n==3) return 1;
else if(n%2==0) return 2*F(n/2);
return F(n/2)+F((n+1)/2);
}
int main()
{
int n;
while(1)
{
cin>>n;
if(n==0) break;
else
cout<<F(n)<<endl;
}
return 0;
}
18441 偷懒的士兵
#include <iostream>
#include <map>
using namespace std;
int F(int n)
{
if(n<3) return 0;
else if(n==3) return 1;
else if(n%2==0) return 2*F(n/2);
return F(n/2)+F((n+1)/2);
}
int main()
{
int n;
while(1)
{
cin>>n;
if(n==0) break;
else
cout<<n-3*F(n)<<endl;
}
return 0;
}
18442 偷懒的士兵2
#include <iostream>
#include <algorithm>
using namespace std;
int F(int n,int Begin,int Dis)
{
if(n<3) return Begin;
if(n==3) return 99999;
int a=F(n/2,Begin+Dis,Dis*2);
int b=F((n+1)/2,Begin,Dis*2);
return min(a,b);
}
int main()
{
int n;
while(cin>>n &&n!=0)
{
if(F(n,1,1)==99999) cout<<"0"<<endl;
else cout<<F(n,1,1)<<endl;
}
return 0;
}
18443 除法等式
#include <iostream>
using namespace std;
int mark(int a,int b)
{
int book[10]= {0};
while(a)
{
book[a%10]++;
a/=10;
}
while(b)
{
book[b%10]++;
b/=10;
}
for(int i=1; i<10; i++)
{
if(book[i]>1) return 0;
}
return 1;
}
int main()
{
int T;
while(cin>>T&&T!=0)
{
for(int i=1; i<=50000; i++)
{
if(i*T>0&&i*T<=98765)
{
if(mark(i*T,i)==1)
{
printf("%05d/%05d=%d\n",i*T,i,T);
}
}
}
cout<<endl;
}
return 0;
}
1079 三角形
#include <iostream>
#include <cmath>
using namespace std;
void deal(int n)
{
for(int i=2051;i>n;i--)
{
int j=sqrt(i*i-n*n);
if(j*j+n*n==i*i)
cout<<i<<','<<j<<endl;
}
for(int i=n-1;i>0;i--)
{
int j=sqrt(n*n-i*i);
if(i*i+j*j==n*n&&i>=j)
cout<<i<<','<<j<<endl;
}
}
int main()
{
int T;
cin >> T;
while (T--)
{
int n;
cin>>n;
deal(n);
cout<<endl;
}
return 0;
}
8623 龙龙
#include<iostream>
#include<algorithm>
using namespace std;
long long H(int n)
{
long long res = 0;
int i,a,b;
for(i=1,a=n;i<a;i=i+1 )
{
res+=a;;
b=n/(i+1);
res+=i*(a-b);
a=b;
}
if(a==i)
res+=a;
return res;
}
int main()
{
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
cout<<H(n)<<endl;
}
return 0;
}
18444 分数拆分
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int k;
while(cin>>k&&k!=0)
{
long long x,y,z;
for(z=k+1;z<=3*k;z++)
{
int p;
p=k*z/(z-k);
if((k*z)%(z-k)==0)
{
y=p;
if(y>=z)
printf("1/%d=1/%lld+1/%lld\n",k,y,z);
}
for(y=p+1;y<=2*p+1;y++)
{
if((k*y*z)%(y*z-k*y-k*z)==0)
{
x=k*y*z/(y*z-k*y-k*z);
if(x>=y&&y>=z)
printf("1/%d=1/%lld+1/%lld+1/%lld\n",k,x,y,z);
}
}
}
cout<<endl;
}
return 0;
}
18124 N皇后问题
#include <iostream>
#include <math.h>
using namespace std;
int ans=0;
int NQueen(int n,int k,int a[])
{
int i,j;
if(k==n)
{
ans++;
}
for(i=0;i<n;i++)
{
for(j=0;j<k;j++)
{
if(a[j]==i||abs(a[j]-i)==abs(k-j))
break;
}
if(j==k)
{
a[k]=i;
NQueen(n,k+1,a);
}
}
}
int main()
{
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
ans=0;
int a[100];
NQueen(n,0,a);
cout<<ans<<endl;
}
return 0;
}
19010 最小的特殊数字
#include <iostream>
#include <algorithm>
using namespace std;
long long n; //多少个数字
long long k; //除数
long long a[20]; //存放n个数字
long long ans=0; //满足条件的最小的数
long long v[20]; //标记数组
long long b[20]; //存放dfs答案的数组,step作为b的数组下标
long long get()
{
long long sum=0;
for(int i=1; i<=n; i++)
sum=sum*10+b[i];
return sum;
}
void dfs(int step)
{
if(step==n+1)
{
if(get()%k==0&&ans==0)
ans=get();
return;
}
for(int i=1; i<=n&&!ans; i++) // !ans等价于ans==0
{
if(step==1&&a[i]==0)
continue;
if(v[i]==0)
{
v[i]=1;
b[step]=a[i];
dfs(step+1);
v[i]=0;
}
}
}
int main()
{
int i,j;
cin>>n>>k;
for(i=1; i<=n; i++)
cin>>a[i];
if(n==1&&a[1]==0)
{
cout<<0;
return 0;
}
sort(a+1,a+n+1); //数组下标从1开始
dfs(1);
if(ans)
cout<<ans;
else
cout<<-1;
return 0;
}
18308 最长公共子序列
#include <iostream>
#include <string.h>
using namespace std;
int dp[1005][1005];
int main()
{
char s1[1005],s2[1005];
cin>>s1>>s2;
int l1=strlen(s1),l2=strlen(s2);
for(int i=1;i<=l1;i++)
{
for(int j=1;j<=l2;j++)
{
if(s1[i-1]==s2[j-1]) dp[i][j]=dp[i-1][j-1]+1;
else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
cout<<dp[l1][l2];
return 0;
}
8615 快乐
#include <iostream>
using namespace std;
int main()
{
int F[51][2001]={0};
int n;
scanf("%d",&n);
int gethappy[n+1],losspow[n+1];
for(int i=1; i<=n; i++)
scanf("%d",&gethappy[i]);
for(int i=1; i<=n; i++)
scanf("%d",&losspow[i]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=2000;j++)
{
if(losspow[i]>=j) F[i][j]=F[i-1][j];
else F[i][j]=max(F[i-1][j],F[i-1][j-losspow[i]]+gethappy[i]);
}
}
cout<<F[n][2000]+1;
return 0;
}
18233 万湖之国的形成
#include <iostream>
#include <algorithm>
using namespace std;
int book[100050];
struct Circle
{
double x;
double y;
double r;
};
Circle circle[100050];
bool compare(Circle a,Circle b)
{
return a.x+a.r<b.x+b.r;
}
int Find(int k)
{
if(book[k]==k) return k;
else return book[k]=Find(book[k]);
}
int main()
{
int n;
int num;
cin>>n;
num=n;
for(int i=0; i<n; i++)
{
cin>>circle[i].x>>circle[i].y>>circle[i].r;
book[i]=i;
}
sort(circle,circle+n,compare);
for(int i=0; i<n; i++)
{
for(int j=i-1; j>=0; j--)
{
if(circle[j].x+circle[j].r<=circle[i].x-circle[i].r)
{
break;
}
if(((circle[j].x-circle[i].x)*(circle[j].x-circle[i].x)+(circle[j].y-circle[i].y)*(circle[j].y-circle[i].y))<(circle[j].r+circle[i].r)*(circle[j].r+circle[i].r))
{
int m,n;
m=Find(i);
n=Find(j);
if(m!=n)
{
num--;
book[m]=n;
}
}
}
}
cout<<num<<endl;
return 0;
}
18130 繁忙的公路
#include <iostream>
using namespace std;
int a[1000005]={0};
int lowbit(int x)
{
return x&(-x);
}
void update(int i,int v,int n)
{
for(;i<=n;i+=lowbit(i))
{
a[i]+=v;
}
}
long long sum(int i)
{
int s=0;
for(;i>0;i-=lowbit(i))
{
s+=a[i];
}
return s;
}
int main()
{
int n;
cin>>n;
int m;
cin>>m;
while(m--)
{
char require;
int i,v;
cin>>require>>i>>v;
if(require=='H')
{
update(i,v,n);
}
if(require=='Q')
{
int res1=sum(v);
int res2=sum(i-1);
cout<<res1-res2<<endl;
}
}
return 0;
}