A题
https://blog.csdn.net/qq_45328552/article/details/103207775
B题
题意:从n个数中选k个数,有多少种选法。
思路:规律,有n-(k-1)中。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
int main()
{
int n,k;
cin>>n>>k;
cout<<n-(k-1)<<endl;
return 0;
}
C题
题意:有n个数从0~n,这n个数重新排列组合成为{p1,p2...pn},让这个新的组合分别对应{0,1,2...n}取余的值相加,问最大值是多少?
思路:例如1,2,3,4,5,6 新的排列的应该为2,3,4,5,6,1 把所有数往前移动一位,第一位移到最后面,这样能使取余结果最大化。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <vector>
using namespace std;
typedef long long ll;
int main()
{
// freopen("input.txt","r",stdin);
ll n;
cin>>n;
ll ans=0;
for(ll i=1;i<n;i++) ans+=i;
cout<<ans<<endl;
return 0;
}
E题
题意:给你n个点分别是第1~n个点距离Di,用这n个点组成一个树,问能组成多少个(即求有多少个满足条件的同分异构体的树)。需要注意的是,这n个点组成的树是n-1条边组成的无向图,而0≤Di≤N−1,故可知每条边的权值为1。
思路:在纸上模拟简单树可知,设ans=1,同分异构体的数目是,第一层节点数目的第二层节点数目次方(ans*=a1^a2),再乘以第二层数目的第三层数目次方(ans*=a2^a3)...直到乘到最后一层。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
const ll mod= 998244353;
ll a[maxn];
ll ksm(ll a,ll n)
{
ll res=1;
while(n)
{
if(n&1) res=res*a%mod;
a=a*a%mod;
n>>=1;
}
return res%mod;
}
int main()
{
ll n;
cin>>n;
ll flag1=0;//用来表示不能形成树的情况
ll Max=0;
for(int i=0;i<n;i++)
{
ll x;
cin>>x;
if(i==0&&x!=0) flag1=1;
a[x]++;
Max=max(Max,x);
}
if(a[0]!=1) flag1=1;
for(int i=0;i<=Max;i++) if(a[i]==0) flag1=1;
ll ans=1;
for(int i=0;i<Max;i++) ans=ans*ksm(a[i],a[i+1])%mod;
if(flag1) ans=0;
cout<<ans%mod<<endl;
return 0;
}
F题
思路:求所有数的最大公约数。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
int a[maxn];
int main()
{
// freopen("input.txt","r",stdin);
int n;
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
sort(a,a+n);
int temp=a[0];
for(int i=1;i<n;i++) temp=__gcd(temp,a[i]);
cout<<temp<<endl;
return 0;
}
G题
算法:贪心。
题意:给你n个需要购买的item的价钱,k个折扣券,每个折扣券能打5折。(最简洁明了题意)
思路:每个折扣券能打5折,你选择用在啥上面,肯定是最贵的上面啊!重复更新,每次给最贵的使用折扣券,即sum/2。
之前想的是用sort排序,但是sort排序的时间复杂度是O(n*log n),这是大于线性但小于平方的复杂度,这样整个程序的复杂度就大于n*m了,肯定会超时。
优先队列的时间复杂度是O(n),小于sort排序的时间复杂度,所以能过。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
priority_queue<int> q;
int main()
{
// freopen("input.txt","r",stdin);
ll n,m;
cin>>n>>m;
for(ll i=0;i<n;i++)
{
int x;
cin>>x;
q.push(x);
}
for(ll i=0;i<m;i++)
{
int temp=q.top();
q.pop();
temp/=2;
q.push(temp);
}
ll ans=0;
for(ll i=0;i<n;i++)
{
int temp=q.top();
q.pop();
ans+=temp;
}
cout<<ans<<endl;
return 0;
}
其实这一题我之前就像放弃了,但是慢慢看题、理解题意,把复杂的题意简单化,慢慢有了思路,出错了,想出了优先队列的解法,没有怕麻烦,又去尝试,没想到竟然成功了。
也让我知道,只要坚持,惊喜就会到来,把题意简单化,思路简单化,换个角度,死磕它,我也能做更多的题。
H题
把n个人的起始k值先全部减去Q,然后遍历给出的Q个数,遍历到的那个人生命值+1,最后如果谁的生命值大于1,输出yes,否则输出no。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
int a[maxn];
int main()
{
// freopen("input.txt","r",stdin);
int n,k,q;
cin>>n>>k>>q;
for(int i=0;i<n;i++) a[i]=k-q;
for(int i=0;i<q;i++)
{
int x;
cin>>x;
a[x-1]++;
}
for(int i=0;i<n;i++)
{
if(a[i]>0) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
I题
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
int a[maxn];
int main()
{
// freopen("input.txt","r",stdin);
ll n;
cin>>n;
int ans=0,res=0;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
for(int i=1;i<n;i++)
{
if(a[i]<=a[i-1]) ans++;
else ans=0;
res=max(res,ans);
}
cout<<res<<endl;
return 0;
}
M题
题意:给你n个字符串,这n个字符串可以任意排列最后组合到一起,问其中“AB”字符串最多有多少。
思路:只单纯的去想有多少个子串是徒劳的,关键是找到普遍规律。每个字符串中可构成AB子串的有AB,...A,B...,B...A。找到这四种元素的个数就能想办法求出答案。AB可以求出,关键是另外三种元素组成AB子串的个数,我是先把B...A的问题解决掉,如果有n个B...A,则能表示成n-1个AB和一个B...A,然后和另外两个元素结合求一下就行了。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
int a[maxn];
int main()
{
// freopen("input.txt","r",stdin);
ll n;
cin>>n;
int ans=0,res=0;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
for(int i=1;i<n;i++)
{
if(a[i]<=a[i-1]) ans++;
else ans=0;
res=max(res,ans);
}
cout<<res<<endl;
return 0;
}
//有n个仓库,m个工人,任何