桂电信科2020程序设计大赛题解

1 奥利给

输出语句

#include<bits/stdc++.h>
using namespace std;
int main(){
    //cout<<"奥利给"<<endl;
    printf("奥利给");
    return 0;
}

2 两极反转数

取位数
注意前置 0 的格式要求

#include<bits/stdc++.h>
using namespace std;
int main(){
    int t,n,k;//k 为了取位数
    int m;//保存取反后的数 
    scanf("%d",&t);
    while(t--){
    	m=0; 
        scanf("%d",&n);
        while(n){
            k=n%10;
            m=m*10+k;
            n/=10;
        }
        printf("%d\n",m);
    }
    return 0;
}

3 打印沙漏

模拟题,根据题意模拟出结果

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    char ch;
    cin>>n>>ch;
    int Max=1;
	int cnt=0;
	for(int i=3;i<=1000;i+=2){
		if(Max+2*i>n){
			break;
		}
		else{
			Max+=2*i; 
			cnt++;
		}
	}
	int t=0; //控制空格
       		 //控制上面的行
	for(int i=cnt;i>=1;i--){
        //打印空格
		for(int k=1;k<=t;k++){
			cout<<" ";
		}
        //打印符号
		for(int j=1;j<=2*i+1;j++){
			cout<<ch;
		}
		cout<<endl;
		t++;
	}
	for(int i=1;i<=t;i++){
		cout<<" ";
	}
	cout<<ch<<endl;
	t--;
	for(int i=1;i<=cnt;i++){
		for(int k=1;k<=t;k++){
			cout<<" ";
		}
		for(int j=1;j<=2*i+1;j++) {
			cout<<ch;
		}
		cout<<endl;
		t--;
	}
	cout<<n-Max<<endl;

    return 0;
}

运行截图

4 数字九

和第二题一样,取位数,判断是不是9,如果是,个数加一,跳转到下一个数字。

#include<bits/stdc++.h>
using namespace std;
int main(){
	int ans=0;
	int p;//取出位数 
    for(int i=1;i<=2020;i++){
    	int n=i;
    	while(n){
    		p=n%10;
    		if(p==9){
    			ans++;
    			break;
			}
    		n/=10;
		}
	} 
	cout<<ans<<endl;
    return 0;
}

或者你已经用肉眼或者纸笔得出结果 544

#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<544<<endl;
    return 0;
}

5 划分字母区域

体现这场比赛区分度的三道题之一
贪心——仔细想“同一个数组最多出现在一个片段里”这句话,以第一个字符找到它最后一次在字符串里出现的位置,然后看这个区间里的其它字符最后一次出现的位置在哪,如果在后面就向后维护一个最大区间。

#include<bits/stdc++.h>
using namespace std;
map<char,int> mp;
int main(){
	int t;
	cin>>t;
	while(t--){
		string s;
		cin>>s;
		while(s.size()){
			char am=s[0];
			int index=0;
			for(int i=1;i<s.size();i++){
				if(am==s[i]){
					index=i;
				}
			}
			for(int i=0;i<=index;i++){
				char bm=s[i];
				for(int j=0;j<s.size();j++){
					if(bm==s[j]&&index<j){
						index=j;
					}
				}
			}
			int len=s.size();
			string str=s.substr(index+1,len-index+1);
			s=str;
			cout<<index+1<<" ";
		}
		cout<<endl;
	}
	return 0;
}
//ababcbacadefegdehijhklij

6 最大子列和问题

四种做法
三循环写好点也不会超时
双循环
二分
还有下面这种

#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
int a[maxn];
int main(){
	int n;
	cin>>n;
	int sum=0,maxsum=0;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		sum+=a[i];
		if(sum>maxsum) maxsum=sum;
		if(sum<0) sum=0;
	}
	cout<<maxsum<<endl;
	return 0;
} 

7 寻找两数的所有公因数

先用辗转相除法求最大公约数,再拆最大公约数

#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
int gcdd(int a,int b){
	int k;
    while(a%b){
    	k=b;
    	b=a%b;
    	a=k;
	}
    return b;
}
int main(){
	int a,b;
	cin>>a>>b;
	int n=gcdd(a,b);
	for(int i=1;i<=n;i++){
		if(n%i==0) cout<<i<<" ";
	}
	return 0;
}

8 表达式计算

体现这场比赛区分度的三道题之一
首先处理一句话,数据可能会出现多余括号情况。
为了括号匹配合理,我们先在字符串的左边预先加入足够多个左括号,用来匹配表达式中出现的右括号。
之后两个栈,一个存数值,一个存操作符,存操作数是为了考虑符号的优先级,最后在出现右括号后,处理距离有括号最近的左括号至右括号之间的数据,然后再存进数值栈中,如此反复,直至字符串处理完毕。

#include<bits/stdc++.h>
using namespace std;
stack<int> num;
stack<int> op;
void cal(){
    int a=num.top();num.pop();
    int b=num.top();num.pop();
    char c=op.top();op.pop();
    int d;
    if(c=='+') d=a+b;
    if(c=='-') d=b-a;
    if(c=='*') d=a*b;
    if(c=='/') d=b/a;
    if(c=='^'){
        d=1;
        while(a--){
            d*=b;
        }
    }
    num.push(d);
}
int main(){
    string str;
    cin>>str;
    string left;
    for(int i=0;i<str.size();i++){
        left+='(';
    }
    str=left+str+')';
    for(int i=0;i<str.size();i++){
        if(str[i]>='0'&&str[i]<='9'){
            int j=i,t=0;
            while(str[j]>='0'&&str[j]<='9'){
                t=t*10+str[j]-'0';
                j++;
            }
            i=j-1;
            num.push(t);
        }else{
            char c=str[i];
            if(c=='+'||c=='-'){
                if(c=='-'&&i&&!(str[i-1]>='0'&&str[i]<='9'||str[i-1]==')')){
                    int j=i+1,t=0;
                    while(str[j]>='0'&&str[j]<='9'){
                        t=t*10+str[j]-'0';
                        j++;
                    }
                    i=j-1;
                    num.push(-t);
                }else{
                    while(op.top()!='('){
                        cal();
                    }
                    op.push(c);
                }
            }else if(c=='*'||c=='/'){
                while(op.top()=='*'||op.top()=='/'||op.top()=='^') cal();
                op.push(c);
            }else if(c=='^'){
                while(op.top()=='^') cal();
                op.push(c);
            }else if(c==')'){
                while(op.top()!='('){
                    cal();
                    
                }
                op.pop();
            }else if(c=='('){
                op.push(c);
            }
        }
    }
    cout<<num.top();
    return 0;
}

9 约瑟夫生者死者小游戏

比赛的时候因为数据只有1~9,所有一共有九种情况,我打表做的。
正解还是模拟环,用链表或者用数组模拟链表。

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int a[31];
	int k=1;
	for(int i=0;i<31;i++){
		a[i]=i;
	}
	int n;
	scanf("%d",&n);
 	for(int i=0;i<15;i++){
 		for(int j=1;j<=n;j++){
 			while((k<31)&&(a[k]==0)){
 				k++;
			}
			if(k==31){
				k=1;
			}
			if(j==n){
				printf("第%d号下船了\n",a[k]);
				a[k]=0;
			}
			k++;
		}	
	}
	return 0;
}

10 拯救007

体现这场比赛区分度的三道题之一
做法肯定是 深搜+最短路
比赛的时候没理出来

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=1010;
struct node{
	int x;
	int y;
}a[maxn];
int n,d;
int pos,dmin=INF;
int dis[maxn][maxn],next[maxn][maxn];
vector<int> ans;
stack<int> st;
void dfs(int x,int y){
	if(next[x][y]==-1){
		if(x!=0){
			st.push(x);
		}
	}else if(next[x][y]!=INF){
		dfs(next[x][y],y);
		dfs(x,next[x][y]);
	}
}
int main(){
	cin>>n>>d;
	for(int i=1;i<=n;i++){
		cin>>a[i].x>>a[i].y;
		if(min(50-abs(a[i].x),50-abs(a[i].y))<=d){
			ans.push_back(i);
		} 
	}
	a[0].x=a[0].y=0;
	memset(dis,INF,sizeof(dis));
	memset(next,INF,sizeof(next));
	for(int i=0;i<=n;i++){
		dis[i][i]=0;
		for(int j=i+1;j<=n;j++){
			double x=0;
			if(i==0) x=7.5;
			double tx=a[i].x-a[j].x;
			double ty=a[i].y-a[j].y;
			double td=d+x;
			if(tx*tx+ty*ty<=td*td){//可以走 
				dis[i][j]=dis[j][i]=1;
				next[i][j]=next[j][i]=-1;
			}
		}
	}
	for(int k=0;k<=n;k++){
		for(int i=0;i<=n;i++){
			if(dis[i][k]==INF) continue;
			for(int j=0;j<=n;j++){
				if(dis[k][j]==INF) continue;
				if(dis[i][j]>dis[i][k]+dis[k][j]){
					dis[i][j]=dis[j][i]=dis[i][k]+dis[k][j];
					next[i][j]=next[j][i]=k;
				}
			}
		}
	}
	int num=INF;
	for(int i=0;i<ans.size();i++){
		num=min(num,dis[0][ans[i]]+1);//+1是在最后一块跳到岸上 
	}
	if(num==INF){
		cout<<"0"<<endl;
		return 0; 
	}
	if(d>=50){
		cout<<"1"<<endl;
		return 0;
	}
	for(int i=0;i<ans.size();i++){
		if(num==dis[0][ans[i]]+1){
			dfs(0,ans[i]);
			int k=st.top();
			double tx=a[k].x;
			double ty=a[k].y;
			if(dmin>tx*tx+ty*ty){
				pos=ans[i];
				dmin=tx*tx+ty*ty;
			}
			while(!st.empty()) st.pop();
		}
	}
	st.push(pos);
	dfs(0,pos);
	cout<<num<<endl;
	while(!st.empty()){
		int k=st.top();
		st.pop();
		cout<<a[k].x<<" "<<a[k].y<<endl;
	}
	return 0;
}
  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值