A - Don’t be late(转换为乘法)
题意:
问是否能在时间 T T T内,到达终点,距离为 D D D,速度为 S S S.
思路:
简单的数学问题。在时间
T
T
T内所能达到的最大距离
d
=
T
d=T
d=T x
S
S
S
如果
d
>
=
D
d>=D
d>=D那么肯定可以按时到达。(转换为乘法,当然啦除法也行,不过有浮点误差)
AC
#include <iostream>
using namespace std;
int main()
{
int d,t,s;
cin>>d>>t>>s;
if(t*s>=d)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
return 0;
}
B - Substring(暴力匹配)
题意:
思路:
为了改变最少的值,使得s中有t。
可以O(
n
2
n^2
n2)的暴力看。
- 在s中枚举起点,且长度为len_t的子串。
- 匹配即可。不相同tmp++。
- 之后ans取一个min即可。(ans=min(ans,tmp))
AC
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s,t;
cin>>s>>t;
int len_s=s.size(),len_t=t.size();
int ans=100000;
for(int i=0; i<=len_s-len_t; i++){
int p1=i,p2,cnt=0;
for(p2=0; p2<len_t; p2++,p1++){
if(s[p1]!=t[p2])cnt++;
}
ans=min(ans,cnt);
}
cout<<ans<<endl;
return 0;
}
C - Sum of product of pairs(前缀和)
题意:
思路:
直接算,肯定超时O( n 2 n^2 n2)。
- 优化思路:先把式子写出来。
- 假如有六项。所有情况枚举如下,ans就是他们的和。
- 可以发现,第一行把 a 1 a_1 a1提取出来,那么剩下的就是( a 2 a_2 a2+ a 3 a_3 a3+ a 4 a_4 a4+ a 5 a_5 a5+ a 6 a_6 a6)
- 其实就是pre【n】-pre【1】。(pre【n】为前缀和)
- 更加一般地就是 a i a_i aix(pre【n】-pre【i】)。
- 模运算注意下。
AC
#include <iostream>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=2e5+10;
ll pre[maxn],a[maxn];
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int n;
cin>>n;
for(int i=1; i<=n; i++){
cin>>a[i];
pre[i]=(pre[i-1]+a[i])%mod;
}
ll ans=0;
for(int i=1; i<=n; i++){
ll tmp=(a[i]%mod)*( (pre[n]+mod-pre[i])%mod )%mod;
ans=(ans+tmp)%mod;
}
cout<<ans<<endl;
return 0;
}
D - Friends(并查集)
题意
有朋友关系,之后要分配最少的小组,使得每个小组中都没有朋友。
思路:
- 先进行并查集的基本操作。
- 之后ans=max(集合中的人数)
- 因为人数最多的朋友圈,肯定是他们都是分配到不同组,那么答案就是它。
AC
#include <iostream>
using namespace std;
const int maxn=2e5+10;
int f[maxn],a[maxn];
int find(int x){
if(x==f[x])return x;
return f[x]=find(f[x]);
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int n,m;
cin>>n>>m;
for(int i=1; i<=n; i++)f[i]=i;
for(int i=1; i<=m; i++){
int a,b;
cin>>a>>b;
int A=find(a),B=find(b);
if(A!=B)f[A]=B;
}
for(int i=1; i<=n; i++)a[find(i)]++;
int ans=0;
for(int i=1; i<=n; i++)ans=max(a[i],ans);
cout<<ans<<endl;
return 0;
}
E - Coprime(筛法)
题意
思路:(主要是pairwise)
- 由于每个元素小,所以先标记一下。
- 之后是否gcd>1.可以利用筛法。
- 筛时,定义一个val。加上之前标记的值(假如val>1,那么就有至少两个数,含当前质因子,不符合“pairwise”)(因为每次都是拿最小的质因子去筛)
- 其他情况算简单。
AC
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=1e6+10;
int a[maxn];
int pri[maxn],vis[maxn];
int gcd(int a, int b){
if(b==0)return a;
return gcd(b,a%b);
}
bool work(){
for(int i=0; i<maxn; i++)pri[i]=1;
pri[1]=pri[0]=0;
for(int i=2; i<maxn; i++){
if(pri[i]){
int val=vis[i];
for(int j=i*2; j<maxn; j+=i){
pri[j]=0;
val+=vis[j];
}
if(val>1)return false;
}
}
return true;
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int n;
cin>>n;
for(int i=1; i<=n; i++)cin>>a[i],vis[a[i]]++;
if(work()){
cout<<"pairwise coprime"<<endl;
return 0;
}
int ans=a[1];
for(int i=1; i<=n; i++)ans=gcd(ans,a[i]);
if(ans==1)cout<<"setwise coprime"<<endl;
else cout<<"not coprime"<<endl;
return 0;
}
AC(赛时代码,码歪了,一堆bug,wa了很多发才过)
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=1e6+10;
int a[maxn];
int pri[maxn],vis[maxn];
int gcd(int a, int b){
if(b==0)return a;
return gcd(b,a%b);
}
bool work(){
int f1=1;
for(int i=0; i<maxn; i++)pri[i]=1;
pri[1]=pri[0]=0;
for(int i=2; i<maxn; i++){
if(pri[i]){
int f2=0;
if(vis[i])f2=1;
for(int j=i*2; j<maxn; j+=i){
pri[j]=0;
if(f2&&vis[j])f1=0;
if(vis[j])f2=1;
if(!f1)return false;
}
}
}
return true;
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int n;
cin>>n;
int mx=0,maxx=0;
for(int i=1; i<=n; i++){
cin>>a[i];vis[a[i]]++;
if(a[i]!=1)mx=max(vis[a[i]],mx);
maxx=max(maxx,a[i]);
}
if(mx<=1){
if(work()){
cout<<"pairwise coprime"<<endl;
return 0;
}
}
int ans=a[1];
for(int i=1; i<=n; i++)ans=gcd(ans,a[i]);
if(ans==1)cout<<"setwise coprime"<<endl;
else cout<<"not coprime"<<endl;
return 0;
}