2019年南海区青少年信息学奥林匹克竞赛(小学甲组)
得分:460分,一等500 (我还是太菜了)
总结:主要是第5题太可惜了(才20分)
下次要理清思路,想好具体做法再做
(似乎历年都是5或6题考贪心)
A. 打印方阵
题目描述
下面这样的方阵很有规律,称为蛇形方阵。例如3×3的:
1 2 3
6 5 4
7 8 9
现在给定边长,输出相应的蛇形方阵。
输入格式
一个整数n,表示要输出n×n的蛇形方阵,1≤n≤100。
输出格式
n行,每行n个整数,空格隔开。
样例
样例输入 1
4
样例输出 1
1 2 3 4
8 7 6 5
9 10 11 12
16 15 14 13
直接暴力,没有细节。
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cmath>
using namespace std;
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
if(i%2==1)
{
for(int j=(i-1)*n+1;j<=i*n;j++)
cout<<j<<" ";
cout<<endl;
}
if(i%2==0)
{
for(int j=i*n;j>=(i-1)*n+1;j--)
cout<<j<<" ";
cout<<endl;
}
}
return 0;
}
B. 分数减法
题目描述
这样的分式运算我们都会。请编程计算两个分数相减的结果。
输入格式
第一行,两个整数a和b,表示一个分数abab,1≤a<b≤10000。
第二行,两个整数c和d,表示一个分数cdcd,1≤c<d≤10000。
输入数据保证计算结果为正。
输出格式
两个整数,表示结果。
提示:运算结果分式要约分。
样例
样例输入 1
4 7
1 3
样例输出 1
5 21
注意结果要约分
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cmath>
using namespace std;
int z1,m1,z2,m2,a1,a2,k;
int main()
{
cin>>z1>>m1>>z2>>m2;
for(int i=1;i<=m1;i++)
{
if(i*m2%m1==0)
k=i*m2;
} //防止int炸(不加也没有关系)
z1=z1*(k/m1);
z2=z2*(k/m2);
a1=z1-z2;
a2=k;
int i=2;
while(i<=a1)
{
if(a1%i==0&&a2%i==0)
a1=a1/i,a2=a2/i;
else
i++;
}//约分
cout<<a1<<" "<<a2;
return 0;
}
C. 倒背如流
题目描述
黑板上老师写了一行N个正整数,老师要考同学们的倒背如流能力,让学生从右向左读这些数字,并求出他们的和。例如写了3个整数:123 45 60。结果是:06+54+321=381
输入格式
第一行,一个整数n,1≤n≤100。
第二行,n个正整数,每个正整数不超过1000000。
输出格式
一个整数。
样例
样例输入 1
3
123 45 60
样例输出 1
381
字符串比较方便
#include<iostream>
#include<fstream>
#include<algorithm>
#include<string>
#include<cmath>//pow函数
using namespace std;
int n;
long long ans;
string s;
int main()
{
cin>>n;
for(int e=1;e<=n;e++)
{
cin>>s;
for(int i=s.size()-1;i>=0;i--)
{
int d=s[i]-'0';
ans=ans+pow(10,i)*d;
}
}
cout<<ans;
return 0;
}
D. 集合的差
题目描述
有两个数列A和B,那些在A中出现但不在B中出现的数就称为集合A和集合B的差:A-B。例如:A={1,4,5,2,6},B={5,3,2,7},那么A-B={1,4,6}。
现在给你2个集合A和B,求A-B有多少个数。
输入格式
第一行,两个整数na和nb,表示集合A和集合B各有多少个整数,1≤na,nb≤10000;
第二行,na个不同的正整数,表示集合A里的数,每个正整数不超过10000;
第三行,nb个不同的正整数,表示集合B里的数,每个正整数不超过10000。
输出格式
一个整数,A-B里有多少数。
样例
样例输入 1
5 4
5 2 4 8 7
3 7 6 2
样例输出 1
3
数据范围与提示
样例说明:
A-B={5,4,8}。
数组统计不会超时,没有细节
#include<iostream>
#include<fstream>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;
int n,a[10005],b[10005],f,ans,m;
int main()
{
cin>>n;
cin>>m;
for(int i=1;i<=n;i++)
{
cin>>f;
a[f]++;
ans++;
}
for(int i=1;i<=m;i++)
{
cin>>f;
if(a[f]==1)
ans--;
}
cout<<ans;
return 0;
}
E. 可表示的数
题目描述
有N个整数从左到右排成一行,如果某个数等于它前面的2个数的和,就称这个数是可以表示的数。问给定的数列里有多少个数是可以表示的数。
输入格式
第一行,一个整数N,表示数列有多少个整数,1≤N≤10000;
第二行,N个正整数,每个正整数不超过10000。
输出格式
一个整数,有多少可表示的数。
样例
样例输入 1
8
5 2 2 3 4 8 7 16
样例输出 1
3
数据范围与提示
样例说明:
4=2+2;8=5+3;7=3+4。
嗷嗷嗷 简直气死,好多细节,我想的太复杂啦!
原始代码:
#include<iostream>
#include<fstream>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;
int n,a[10005],f,ans;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>f;
a[f]=i;
}//这样只要一有重复的,数组就会被覆盖掉
for(int i=1;i<=10000;i++)
{
for(int j=1;j<=10000;j++)
{
if(a[i]!=0&&a[j]!=0&&a[i+j]!=0&&a[i+j]!=-1)
{
if(a[i]<=a[i+j]&&a[j]<=a[i+j])
{
ans++;
a[i+j]=-1;
}
}
}
}//当时的逻辑好清奇,我到现在也想不通当时为什么要这样写……
cout<<ans;
return 0;
}
AC代码:
#include<iostream>
#include<fstream>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;
int n,a[10005],c[20005],ans;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i-1;j++)//往前找,保证是前面两个
{
c[a[i]+a[j]]=1;//防止出现多个加起来相同的数
}
ans=ans+c[a[i]];//如果有相同的数字,那它也会++,妙哉
}//我觉得有点类似素数筛法
cout<<ans;
return 0;
}
好气哦~
F.叠罗汉
题目描述
农场的N头奶牛喜欢玩叠罗汉游戏,就是几头奶牛1头奶牛接着1头奶牛的站成一柱子形状。不过奶牛的力量不一样,用数值Ci表示第i头奶牛它的上面最多可以站多少头奶牛,问这些奶牛最少可以站成几个柱子形状。
输入格式:
第一行,1个整数N,表示有多少头奶牛,1≤N≤1000;
第二行,N个正整数Ci,表示这些奶牛的力量,0≤Ci≤1000。
输出格式:
一个整数,表示最少成几个“罗汉”。
样例
输入样例:
5
0 2 1 2 2
输出样例:
2
数据范围与提示
样例说明:
可以第1、第3、第2头奶牛从上向下叠罗汉;
第4、第5头奶牛叠罗汉。
#其实就是贪心,考试时也想到了,但做法太复杂了(做对了还好,但问题是没对啊!)。
基本思想,从大到小放。(基本都能想到)
但如果相同,到底放不放?
如果放,后面就有点亏
如果不放,做到最后还不放答案就错了(考试时一直再纠结)
所以,就不要考虑放不放的问题吧,直接从小到大,从上到下叠,能放就放,不能就随缘吧:D (这招是一个大神想出来的,好厉害,膜拜)
AC代码:
#include<iostream>
#include<fstream>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;
int n,f,ans,c[10005],k,d;
int main()
{
//freopen("638.in","r",stdin);
//freopen("638.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>f;
c[f]++;
}
while(k<n)
{
d=0;//要承受多少只
ans++;
for(int i=0;i<=1000;)//注意0
{
if(c[i]!=0&&i>=d)
{
c[i]--;//考虑多只奶牛f相同
k++;
d++;
}
else
i++;
}
}
cout<<ans;
return 0;
}
ε=(´ο`*))) 这次考得好烂啊