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;
}