前言:有亿点点题没做完,后面应该也许大概会补
第一题:easy,照题意模拟就行有80%的人都对了(比赛5个人),注意判断的时间是2024年(今夕是何年?)
代码如下:
#include<bits/stdc++.h>
using namespace std;
int n;
int main(){
cin>>n;
while(n--){
int t;
cin>>t;
if(t<2024){
if(t%4==0&&t%100!=0||t%400==0){
printf("%d was a leap year.\n",t);
}
else{
printf("%d was a common year.\n",t);
}
}
else if(t==2024){
if(t%4==0&&t%100!=0||t%400==0){
printf("%d is a leap year.\n",t);
}
else{
printf("%d is a common year.\n",t);
}
}
else if(t>2024){
if(t%4==0&&t%100!=0||t%400==0){
printf("%d will be a leap year.\n",t);
}
else{
printf("%d will be a common year.\n",t);
}
}
}
return 0;
}
第二题:这题看着很复杂,其实很简单,给你商品价格并且告诉你买b送一,然后问你买X件应该买多少,可以省多少钱。(但是没人AC)
买多少依然简单,设买xXb件(X是乘号因为helloworld使用的神奇HTML写星号是斜体),我们要让xXb+x<购买总件数且x取最大值(不是购买总件数直接除以b不然会有免费的件数被浪费),接下来算省了多少和送几个非常简单
But,这题有几个坑人点要注意:1.商品名称有空格,记得用getline
2.商品价格给的美分有点奇妙,正常来说18美分=0.18美元,所以很容易写成价格=美元+美分/100,但是本题在美分处如果输入一个3却是0.3美元而不是0.03美元
3.如果你买了xXb件,免费的件数不等于x,比如一共有20件,每买6件送一件,那么买三个六件实际上只帮你免费了2件而不是3件,所以省的件数要注意判断是取x件还是(总件数-xXb)件。
然后没什么了,但是这题没有一个人AC,所以这里只有60分代码(改了几遍没改出来):
#include<bits/stdc++.h>
using namespace std;
string s;
double pd,pc;
int b;
int e;
int pf(int x){
int sum=1;
if(x<=e){
return x;
}
else{
while(b*sum+sum<=x){
sum++;
}
sum--;
}
int ans=sum*b;
ans+=(x-ans-sum);
return ans;
}
double sav(int fre){
double c=pd;
if(pc/10>=1){
c+=pc/100;
}
else{
c+=pc/10;
}
return c*fre;
}
int main(){
getline(cin,s);
cin>>pd>>pc;
cin>>b;
cin>>e;
cout<<s<<endl;
while(e--){
int t;
cin>>t;
int ans1=pf(t);//买多少
int ans2=min(ans1/b,t-ans1);//送几件
double ans3=sav(ans2);//省多少钱
printf("Buy %d, pay for %d, get %d free. Save $%.2f.\n",t,ans1,ans2,ans3);
}
return 0;
}
第三题简单到爆,一个xXy的表格里面有若干件东西分布在任意处,然后问你在若干处地方一共有多少件东西,用一个数组a[x][y]表示在(x,y)处有几件东西,询问时把数量加起来就行
代码:
#include<bits/stdc++.h>
using namespace std;
int x,y;
int m;
int a[101][101];
int n;
int sum=0;
int main(){
cin>>x>>y;
cin>>m;
memset(a,0,sizeof(a));
for(int i=1;i<=m;i++){
cin>>x>>y;
a[x][y]++;
}
cin>>n;
for(int i=1;i<=n;i++){
cin>>x>>y;
sum+=a[x][y];
}
cout<<sum;
return 0;
}
第四题也简单,8场比赛,告诉你每场比赛几比几,然后按照规则加分和记录进球平局
但是我有一个小小的问题:题目说了如果没有进球平局,则显示一行:No scoring draws,但是加上这句话60分:
#include<bits/stdc++.h>
using namespace std;
string s[9];
int sum=0;
bool f[9];
bool none=true;
int main(){
memset(f,false,sizeof(f));
getline(cin,s[1]);
for(int i=2;i<=8;i++){
getline(cin,s[i]);
}
for(int i=1;i<=8;i++){
int x,y;
cin>>x>>y;
if(x==y&&x>0&&y>0){
sum+=3;
f[i]=true;
none=false;
}
else if(x==y&&x==0&&y==0){
sum+=2;
}
else{
sum+=1;
}
}
cout<<"Points scored: "<<sum<<endl;
if(none){
cout<<"No scoring draws";
}
else{
for(int i=1;i<=8;i++){
if(f[i]){
cout<<s[i]<<endl;
}
}
}
return 0;
}
把No scoring draws删了之后就100分了
AC代码:
#include<bits/stdc++.h>
using namespace std;
string s[9];
int sum=0;
bool f[9];
bool none=true;
int main(){
memset(f,false,sizeof(f));
getline(cin,s[1]);
for(int i=2;i<=8;i++){
getline(cin,s[i]);
}
for(int i=1;i<=8;i++){
int x,y;
cin>>x>>y;
if(x==y&&x>0&&y>0){
sum+=3;
f[i]=true;
none=false;
}
else if(x==y&&x==0&&y==0){
sum+=2;
}
else{
sum+=1;
}
}
cout<<"Points scored: "<<sum<<endl;
for(int i=1;i<=8;i++){
if(f[i]){
cout<<s[i]<<endl;
}
}
return 0;
}
第五题也很简单,给你一串数字算出来它加上校验码应该是多少,这里建议用字符串操作,照题意模拟就行
AC代码:
#include<bits/stdc++.h>
using namespace std;
string s;
string add(string s){
long long sum=0;
int t=2;
for(int i=s.size()-1;i>=0;i--){
sum+=(int)(s[i]-'0')*t;
t++;
sum%=11;
}
sum%=11;
sum=11-sum;
sum%=11;
if(sum==10){
return "rejected";
}
string ans=s;
ans+=(char)(sum+'0');
return ans;
}
int main(){
while(true){
cin>>s;
if(s=="0"){
break;
}
else{
cout<<s<<" -> "<<add(s)<<endl;
}
}
return 0;
}
第六题还是很简单,给你一个表格让你找出其中的所有非16进制字符输出然后输出每一行的数值(例如A ! 2中!不是16进制字符,剩下A2的数值是162)
什么你说你不知道怎么算16进制,那你回语法班上几天吧
注意点:输出的非16进制符号之间没有空格(加了空格40分)
AC代码:
#include<bits/stdc++.h>
using namespace std;
int n;
char a[11][11];
bool f[11][11];
int trans(string s){
int sum=0;
for(int i=0;i<s.size();i++){
sum*=16;
if(s[i]>='0'&&s[i]<='9'){
sum+=(int)(s[i]-'0');
}
else if(s[i]>='A'&&s[i]<='F'){
sum+=(int)(s[i]-'A'+10);
}
}
return sum;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
if(a[i][j]>='0'&&a[i][j]<='9'||a[i][j]>='A'&&a[i][j]<='F'){
f[i][j]=true;
}
else{
f[i][j]=false;
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(!f[i][j]){
cout<<a[i][j];
}
}
}
cout<<endl;
for(int i=1;i<=n;i++){
string s="";
for(int j=1;j<=n;j++){
if(f[i][j]){
s+=a[i][j];
}
}
cout<<trans(s)<<endl;
}
return 0;
}
第七题对头和骑士的大小从小到大进行排序,这么做是为了防止一个身高有208200的骑士只去砍一个1直径的头,用t表示砍到了第几个头,如果一个骑士的身高大于第t个头就让这个骑士去(因为我们从小到大排序所以第一个身高大于第t个头直径的骑士一定是花费最小的)
AC代码:
#include<bits/stdc++.h>
using namespace std;
int a[20001],b[20001];
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<=m;i++){
scanf("%d",&b[i]);
}
sort(a+1,a+n+1);
sort(b+1,b+m+1);
int ans=0;
int t=1;
for(int i=1;i<=m;i++){
if(b[i]>=a[t]){
t++;
ans+=b[i];
}
if(t>n){
break;
}
}
if(t<=n){
cout<<"Loowater is doomed!";
}
else{
cout<<ans;
}
return 0;
}
第八题:经过我的不懈努力,李凌宇交出了他的程序,但是有亿点点复杂,具体思路去找李凌宇问
AC程序:
#include<iostream>
#include<cmath>
using namespace std;
struct node{
int x;
string name;
};
pair<node,node> a,b;
int main(){
cin>>a.first.name>>a.first.x;
cin>>a.second.name>>a.second.x;
cin>>b.first.name>>b.first.x;
cin>>b.second.name>>b.second.x;
if(a.first.x>a.second.x){
swap(a.first,a.second);
}
if(b.first.x>b.second.x){
swap(b.first,b.second);
}
int maxx=max(b.first.x,a.second.x)-min(b.first.x,a.second.x);
int minn=max(b.second.x,a.first.x)-min(b.second.x,a.first.x);
if(maxx/2*2==maxx&&minn/2*2==minn){
minn=minn/2;
maxx=maxx/2;
}else if(maxx/2*2==maxx&&minn/2*2!=minn){
minn=ceil(minn*1.0/2);
maxx=maxx/2;
}else if(maxx/2*2!=maxx&&minn/2*2==minn){
maxx=ceil(maxx*1.0/2);
minn=minn/2;
}else{
maxx=ceil(maxx*1.0/2);
minn=floor(minn*1.0/2);
}
if(minn==0){
string t1=a.first.name;
string t2=b.second.name;
if(a.first.x<b.second.x){
swap(t1,t2);
}
cout<<"No free turns between "<<t1<<" and "<<t2<<".";
}else{
string t1=a.first.name;
string t2=b.second.name;
if(a.first.x<b.second.x){
swap(t1,t2);
}
cout<<t1<<" receives "<<minn<<" free turns from "<<t2<<".";
}
cout<<endl;
if(maxx==0){
string t1=a.second.name;
string t2=b.first.name;
if(a.second.x<b.first.x){
swap(t1,t2);
}
cout<<"No free turns between "<<t1<<" and "<<t2<<".";
}else{
string t1=a.second.name;
string t2=b.first.name;
if(a.second.x<b.first.x){
swap(t1,t2);
}
cout<<t1<<" receives "<<maxx<<" free turns from "<<t2<<".";
}
return 0;
}
第九题我们需要用一个叫做并查集的东西
首先我们可以轻松算出每个点开始第一步流向哪。
然后就可以开始并查集
合并完之后,我们从左上角扫到右下角,如果这个点的所属流域没有字母,那就给它一个,一直扫下去。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,h[101][101];
int fa[10001],v[10001];
int id(int x,int y){
return (x-1)*m+y;
}
int find(int x){
if(fa[x]==x){
return x;
}
return fa[x]=find(fa[x]);
}
int dx[4]={-1,0,0,1};
int dy[4]={0,-1,1,0};
void f(int x,int y){
int minn=INT_MAX;
for(int i=0;i<4;i++){
int nx=x+dx[i];
int ny=y+dy[i];
if(nx<1||nx>n||ny<1||ny>m){
continue;
}
minn=min(minn,h[nx][ny]);
}
if(minn>=h[x][y]){
return;
}
for(int i=0;i<4;i++){
int nx=x+dx[i],ny=y+dy[i];
if(nx<1||nx>n||ny<1||ny>m){
continue;
}
if(h[nx][ny]==minn){
fa[find(id(x,y))]=find(id(nx,ny));
break;
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>h[i][j];
}
}
for(int i=1;i<=n*m;i++){
fa[i]=i;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
f(i,j);
}
}
int cnt=0;
for(int i=1;i<=n*m;i++){
if(!v[find(i)]){
v[find(i)]=++cnt;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cout<<char('a'+v[find(id(i,j))]-1)<<" ";
}
cout<<endl;
}
return 0;
}