题目链接
由于比赛已经结束,附上每个题目的链接
A【深基2.例7】数字反转
B【深基3.例3】闰年判断
C【深基3.习8】三角形分类
D【深基4.例13】质数口袋
E【深基5.例7】工艺品制作
F【深基7.例1】距离函数
G【深基7.例10】旗鼓相当的对手 - 加强版
H【深基9.例4】求第 k 小的数
I 【深基16.例1】淘汰赛
昨天也是第一次参加洛谷的比赛,个人觉得比赛还是不错的可以锻炼一下自己,检验一下自己学的扎不扎实,更利于查漏补缺!!!
对代码有疑惑或者不明白的地方直接发评论区即可~
下面附上每个题目的AC代码
A 数字反转
直接逆序输出即可
//直接利用string存储逆序输出
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string a;
cin>>a;
for(int i=a.length()-1;i>=0;i--)cout<<a[i];
}
B 闰年判断
判断闰年的条件:能被 4 整除,但是不能被100整除或者能被400整除
#include<bits/stdc++.h>
using namespace std;
int main() {
long long y;
cin>>y;
if(y%400==0||y%4==0&&y%100!=0)//闰年判断条件
{
cout<<1<<endl;
}
else
{
cout<<0<<endl;
}
return 0;
}
C 三角形分类
先判断输入的三条边是否合法,然后根据边来判断三角形的属性,满足一条输出一条即可。
#include<bits/stdc++.h>
using namespace std;
int main() {
int a,b,c;
cin>>a>>b>>c;
if(a+b<=c||a+c<=b||c+b<=a) {
cout<<"Not triangle"<<endl;
return 0;
}
if(a*a+b*b==c*c||c*c+b*b==a*a||a*a+c*c==b*b) {
cout<<"Right triangle"<<endl;
} else if(a*a+b*b<c*c||c*c+b*b<a*a||a*a+c*c<b*b) {
cout<<"Obtuse triangle"<<endl;
} else if(a*a+b*b>c*c||c*c+b*b>a*a||a*a+c*c>b*b) {
cout<<"Acute triangle"<<endl;
}
if(a==b||b==c||a==c) {
cout<<"Isosceles triangle"<<endl;
}
if(a==b&&b==c) {
cout<<"Equilateral triangle"<<endl;
}
return 0;
}
D 质数口袋
判断质数的方法:根据数论理论可以把数字分成6个大部分,6i,6i+1,6i+2,6i+3,6i+4,6i+5,也就是说数字x%6计算的值一定是0,1,2,3,4,5这6个数字,而6i,6i+2,6i+3,6i+4一定就是合数,它们都有除了1之外的因数,只有6i+1和6i+5可能是素数,因而一旦判定数字大于等于且6取模结果为0,2,3,4就可以判定不是素数。
#include<bits/stdc++.h>
using namespace std;
bool vis;
int check(int temp) {
if(temp==1||temp==2||temp==3) {
return 1;
} else if(temp%6!=1&&temp%6!=5) {
return 0;
}
for(int i=5; i<=sqrt(temp); i+=6) {
if(temp%i==0||temp%(i+2)==0) {
return 0;
}
}
return 1;
}
int main() {
int L,sum=0,num=0;
cin>>L;
if(L==1)
{
cout<<0<<endl;
return 0;
}
for(int i=2;i<=L;i++){
if(check(i)){
sum+=i;
num++;
if(sum>L){
vis=1;
}
else
{
cout<<i<<endl;
}
}
if(vis){
sum-=i;
num--;
break;
}
}
cout<<num<<endl;
return 0;
}
E 工艺品制作
这个题目直接暴力求解,枚举所有点的状态进行统计即可,要注意一点就是每个输入的点也会被蒸发。
#include<bits/stdc++.h>
using namespace std;
int a[100][100][100];
int main(){
int w,x,h,q,sum=0;
int x1,x2,y1,y2,z1,z2;
cin>>w>>x>>h>>q;
while(q--){
cin>>x1>>y1>>z1>>x2>>y2>>z2;
for(int i=x1;i<=x2;i++){
for(int j=y1;j<=y2;j++){
for(int t=z1;t<=z2;t++){
a[i][j][t]=1;
//cout<<i<<" "<<j<<" "<<t<<endl;
}
}
}
}
for(int i=1;i<=w;i++){
for(int j=1;j<=x;j++){
for(int t=1;t<=h;t++){
if(!a[i][j][t]){
sum++;
}
}
}
}
cout<<sum<<endl;
return 0;
}
F 距离函数
直接用两点间距离公式求即可
#include<bits/stdc++.h>
using namespace std;
int main() {
double x1,y1,x2,y2,x3,y3,l1,l2,l3;
cin>>x1>>y1>>x2>>y2>>x3>>y3;
l1=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
l2=sqrt((x3-x2)*(x3-x2)+(y3-y2)*(y3-y2));
l3=sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3));
printf("%.2f\n",l1+l2+l3);
return 0;
}
G 旗鼓相当的对手 - 加强版
这个题目注意输出顺序即可,我没仔细读题WA了好多次
先对一个组内的排序,将字典序小的放到前面,然后对组合进行排序,先把每个组里第一个拿出来比较,如果相等比较第二个,将字典序小的放到前面。
#include<bits/stdc++.h>
using namespace std;
struct stu {
string name;
int sc[5];
int all;
} s[105000];
struct zan {
string name1;
string name2;
} tu[105000];
bool cmp(zan a,zan b) {
if(a.name1==b.name1) {
return a.name2<b.name2;
} else {
return a.name1<b.name1;
}
}
int main() {
int n,d=0,num=0;
cin>>n;
for(int i=0; i<n; i++) {
//cin>>s[i].sc[0]>>s[i].sc[1]>>s[i].sc[2];
cin>>s[i].name>>s[i].sc[0]>>s[i].sc[1]>>s[i].sc[2];
s[i].all=s[i].sc[0]+s[i].sc[1]+s[i].sc[2];
}
for(int i=0; i<n; i++) {
for(int j=i+1; j<n; j++) {
if(abs(s[i].all-s[j].all)<=10) {
int temp=0;
if(abs(s[i].sc[0]-s[j].sc[0])<=5&&abs(s[i].sc[1]-s[j].sc[1])<=5&&abs(s[i].sc[2]-s[j].sc[2])<=5) {
temp=1;
}
if(temp==1) {
if(s[i].name<s[j].name) {
tu[d].name1=s[i].name;
tu[d].name2=s[j].name;
d++;
} else {
tu[d].name1=s[j].name;
tu[d].name2=s[i].name;
d++;
}
}
}
}
}
sort(tu,tu+d,cmp);
for(int i=0; i<d; i++) {
cout<<tu[i].name1<<" "<<tu[i].name2<<endl;
}
return 0;
}
H 求第 k 小的数
这个道题就比较(keng)好了
sort函数直接TLE
自己写了一个优化的快排还是超
改了n(忘记多少次了)次终于不超了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int patition(int a[], int left, int right){ //对 left ~ right 进行划分
int x = a[left];
while(left < right){
while(left<right && a[right]>=x)
right--;
a[left] = a[right];
while(left<right && a[left]<=x)
left++;
a[right] = a[left];
}
a[left] = x;
return left;
}
void find(int a[], int left, int right, int k){ //在 left ~ right 寻找
int pos = patition(a, left, right);
if(pos == k)
printf("%d\n", a[pos]);
else if(pos > k)
find(a, left, pos-1, k);
else
find(a, pos+1, right, k);
}
int main(){
int n, k, a[5000005];
scanf("%d%d", &n, &k);
k++;//题目要求是从0开始,我下面写的下标是从1开始的,因此加1
for(int i=1; i<=n; i++)
scanf("%d", a+i);
find(a, 1, n, k);
}
I 淘汰赛
看起来很麻烦,无从下手,仔细分析题意
其实就是数组前一半的最大值与后一半的最大值比较,找到小的值的下标
#include<bits/stdc++.h>
using namespace std;
int a[1024];
int main() {
int n,all,c,b,max1,max2;
cin>>n;
all=pow(2,n);
for(int i=1; i<=all; i++) {
cin>>a[i];
}
//cout<<a[1]<<" "<<a[all/2+1]<<endl;
//cout<<all/2+1<<endl;
c=1;
b=all/2+1;
max1=a[1],max2=a[all/2+1];
for(int i=1; i<=all/2; i++) {
if(a[i]>max1) {
c=i;
max1=a[i];
}
if(a[i+all/2]>max2) {
b=i+all/2;
max2=a[i+all/2];
}
}
//cout<<c<<b<<endl;
if(max2>max1) {
cout<<c<<endl;
} else {
cout<<b<<endl;
}
return 0;
}
转载务必附上本文链接!!!