晚自习玩了一下哈理工新生赛,发现自己还是太弱了啊啊啊
今天补了一些题目,不过因为考试在急就没补完(其实是由于太菜连题解也看不懂!)
有些题目请教了fjy和ph两位大佬,非常感谢两位大佬对我这个蒟蒻的指点%%%
代码风格可能比较烂,而且解法并不是最优秀的,希望大家包容。不正确的地方可以评论区评论一下awa
前10题考试题不做详述(E题可以康康)
A
#include<bits/stdc++.h>
using namespace std;
int main()
{
printf("V V\n");
printf(" V V\n");
printf(" V V\n");
printf(" V\n");
return 0;
}
B
#include<bits/stdc++.h>
using namespace std;
int main()
{
double a,b;
cin>>a>>b;
printf("%.3lf",b/a*100);
printf("%");
return 0;
}
C
#include<bits/stdc++.h>
using namespace std;
int main()
{
int m,n;
cin>>m>>n;
if(m%n==0)printf("YES");
else printf("NO");
return 0;
}
D
#include<bits/stdc++.h>
using namespace std;
int main()
{
int m,n;
int h1,m1,h2,m2,h3=0,m3=0;
cin>>h1>>m1>>h2>>m2;
if(m1>m2)
{
h3=-1;
m2+=60;
}
h3+=h2-h1;
m3=m2-m1;
cout<<h3<<" "<<m3;
return 0;
}
E
个人觉得字符串处理方便一些,主要是看数字出现频率
这里用了map,大家也可以用桶排序(参考I题)实现排序+统计数量的操作(不过要注意数量都是0的情况)
#include<bits/stdc++.h>
using namespace std;
map<char,int>ma,mb;
int main()
{
string a,b;
cin>>a>>b;
for(int i=0;a[i];i++)ma[a[i]]++;
for(int i=0;b[i];i++)mb[b[i]]++;
if(a==b)cout<<100;
else
{
int flag=1,cnt=0;
for(char i='0';i<='9';i++)
{
//cout<<i<<" "<<ma[i]<<" "<<mb[i]<<endl;
if(ma[i]==mb[i]&&ma[i]>0&&mb[i]>0)cnt++;
else if(ma[i]!=mb[i])flag=0;
}
if(flag)cout<<20;
else if(flag==0&&cnt>0)cout<<2;
else if(flag==0&&cnt==0)cout<<0;
}
return 0;
}
F
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cout<<"China will win the battle against COVID-19."<<endl;
return 0;
}
G
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N];
int main()
{
double n,sum=0.0;
int maxn=-100,minn=200;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum+=a[i];
if(a[i]>maxn)maxn=a[i];
if(a[i]<minn)minn=a[i];
}
printf("%.2lf %d %d",sum/n,maxn,minn);
return 0;
}
H
这可能是前10题里我做得最丢人的一题了,写了n*n方阵反复调了五六次,这类题打印图形的题目可以自己画几个找找规律(比如和,差相同啊啥的,等差数列啊啥的)
打印的话分两种,一种是用二维数组(本题做法),一种是直接printf打印(A题做法)
#include<bits/stdc++.h>
using namespace std;
char mp[1000][1000];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=2*n-1;j++)
{
if(i==j||i+j==2*n)mp[i][j]='V';
else mp[i][j]=' ';
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=2*n-1;j++)
{
cout<<mp[i][j];
}
cout<<endl;
}
}
I
桶排序(可以用来完成去重,排序,统计元素个数)
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int a[N],flag[N];//a用来桶排序,flag标记是否已经输出过了
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
a[x]++;
}
for(int i=10000;i>=1;i--)
{
if(a[i]>0&&!flag[i])
{
flag[i]=1;
cout<<i<<"-"<<a[i]<<endl;
}
}
return 0;
}
J
子区间求和,一维前缀和算法,注意对不正常p,q区间的调整。
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
long long a[N],s[N];
int main()
{
int n,t,p,q;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
s[i]=s[i-1]+a[i];
//cout<<s[i]<<endl;
}
cin>>t;
while(t--)
{
cin>>p>>q;
int flag=1;
if(q>n)
{
if(p>n)
{
cout<<0<<endl;
flag=0;
}
q=n;
}
if(p<1)p=1;
if(flag)cout<<s[q]-s[p-1]<<endl;
}
return 0;
}
K
找最大反向搜
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m,k;
int flag=1;
cin>>n>>m>>k;
for(int i=k;i>=1;i--)
{
if(i%n==0&&i%m==0)
{
cout<<i;
flag=0;
break;
}
}
if(flag)cout<<-1;
return 0;
}
L
高中排列组合(高考完记忆删除呜呜呜)含重复元素的排列,这个有公式的自己百度“重复元素的排列”
#include<bits/stdc++.h>
using namespace std;
int flag[30];
long long f(int n)
{
long long q=1;
for(int i=1;i<=n;i++)q*=i;
return q;
}
int main()
{
string s;
int cnt=0,n=0;
cin>>s;
for(int i=0;s[i];i++)
{
// if(flag[s[i]-'A']==0)cnt++;
flag[s[i]-'A']++;
++n;
}
long long res=f(n);
// cout<<res<<endl;
for(int i=0;i<=25;i++)
{
if(flag[i]>0)
{
int t=f(flag[i]);
res=res/t;
}
}
cout<<res-1;
return 0;
}
M
最大-最小+1即可
最大(n-1)max+min
最小(n-1)min+max
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long n,minn,maxn;
cin>>n>>minn>>maxn;
cout<<((n-1)*maxn+minn)-(maxn+(n-1)*minn)+1;
return 0;
}
N
约数个数为3可以推出这些数一定是质数的完全平方
除了1,一个数都有1和其本身两个约数,此时我们还需要一个约数
然后可能涉及如下一些结论(可能表述不是很好,建议百度一波)
1一般情况下约数总是成对出现的,如果要单次出现那么就是这一对约数相同。
2约数是奇数是完全平方数的充要条件
3唯一分解定理和约数个数定理
此时再经过一波观察规律(我承认是我数论知识太浅薄了,真让我说可能误人子弟)
唯 一 分 解 定 理 : N = p 1 c 1 p 2 c 2 p 3 c 3 p 4 c 4 p 5 c 5 … … 约 数 个 数 ( c 1 + 1 ) ( c 2 + 1 ) ( c 3 + 1 ) ( c 4 + 1 ) … … 唯一分解定理:N=p_1^{c_1}p_2^{c_2}p_3^{c_3}p_4^{c_4}p_5^{c_5}……\\ 约数个数(c_1+1)(c_2+1)(c_3+1)(c_4+1)……\\ 唯一分解定理:N=p1c1p2c2p3c3p4c4p5c5……约数个数(c1+1)(c2+1)(c3+1)(c4+1)……
约数个数只能是(2+1)(0+1)(0+1)……
这种组合,那么就只有一个p^2这种可能,即质数的完全平方数
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
bool is_prime(LL x)//开long long!
{
if (x < 2) return false;
for (int i = 2; i <= x / i; i ++ )//不写i*i<=x或者i<=sqrt(x)
if (x % i == 0)
return false;
return true;
}
int main()
{
LL n,cnt=0;
cin>>n;
for(LL i=2;i<=n/i;i++)
{
if(is_prime(i))cnt++;
}
cout<<cnt;
}
O
这题很妙!
第i堆取i,标准重量(N+1)N/2,如果第r堆有问题,那么就会比标准多出r
即可直接知道第几堆。特判1即可
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
if(n==1)cout<<0;
else cout<<1;
return 0;
}
P
因为p>0,所以避不开可能是奇数或者<6的
然后想想能不能二进制表示,然后看有几个1
我们要<=3个1,那么为何要小于呢,因为如果三个指数有相同的话就会合并啦,然后利用STL bitset实现即可
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
bitset<100>b(n);
if(n<6||n%2==1)puts("NO");
else
{
if(b.count()<=3)puts("YES");
else puts("NO");
}
}
Q
先输出一波1/n找规律,只有完全被2或者5整除的ok啦
三种:只能被2整除;只能被5整除;同时被2,5整除(即10)
#include<bits/stdc++.h>
using namespace std;
int n;
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n;
int tmp=n;
if(tmp==1)puts("YES");
else
{
while(1)
{
if(tmp%5==0&&tmp%2!=0)tmp/=5;
else if(tmp%2==0&&tmp%5!=0)tmp/=2;
else if(tmp%2==0&&tmp%5==0)tmp/=10;
else
{
if(tmp==1)
{
puts("YES");
break;
}
else
{
puts("NO");
break;
}
}
}
}
}
return 0;
}
剩下三题补不动了,大佬们有思路的话可以在评论区留言哟
反思:目前个人数论知识方面比较欠缺,博弈论,计算几何balabala
然后记得看清数据范围,开long long!。
然后这里放一个ph和我这蒟蒻聊到半夜的脑洞(坐等博客):将P题推广到底数为n,并由k个n^r组成,判断输入的数是否能被表示出来