To_Heart—题解——「abc177」 题解报告

A.Don't be late

题目链接

题解

按题意模拟即可

#include<bits/stdc++.h>
using namespace std;
#define db double

db d,t,s;


int main(){
    
    
	cin>>d>>t>>s;
	db ans=d/s;
	if(ans<=t){
    
    
		printf("Yes\n");
		return 0;
	}
	cout<<"No"<<endl;
	return 0;
}

B.Substring

题目链接

题解

暴力O( n 2 n^2 n2)模拟即可

#include<bits/stdc++.h>
using namespace std;

char a[2005];
char b[2005];
char aa[2005],bb[2005];

int len1,len2;

int main(){
    
    
	cin>>(aa+1);
	cin>>(bb+1);
	len1=strlen(aa+1),len2=strlen(bb+1);
	if(len1<len2){
    
    
		for(int i=1;i<=len2;i++){
    
    
			a[i]=bb[i];
		}
		for(int i=1;i<=len1;i++){
    
    
			b[i]=aa[i];
		}
		swap(len1,len2);
	}
	else{
    
    
		for(int i=1;i<=len1;i++){
    
    
			a[i]=aa[i];
		}
		for(int i=1;i<=len2;i++){
    
    
			b[i]=bb[i];
		}
	}
	int ans=len1+len2;
	for(int i=1;i<=len1-len2+1;i++){
    
    
		int now=len2;
		for(int j=1;j<=len2;j++){
    
    
			if(a[i+j-1]==b[j])	now--;
		}
		ans=min(now,ans);
	}
	cout<<ans<<endl;
}
 

C.Sum of product of pairs

题目链接

题解

乘法分配律结合即可

#include <bits/stdc++.h>
using namespace std;
#define u unsigned
#define ll long long
#define ull u ll
const ull Mod = 1e9 + 7;

ll sum = 0;
ll ans = 0;
int n;
ll a[200005];

int main() {
    
    
    cin >> n;
    for (int i = 1; i <= n; i++) {
    
    
        scanf("%lld", &a[i]);
        sum += a[i];
    }
    for (int i = 1; i <= n; i++) {
    
    
        ans += (a[i] * ((sum - a[i]) % Mod));
        ans %= Mod;
        sum -= a[i];
    }
    printf("%lld", ans);
    return 0;
}

D.Friends

题目链接

题解

并查集,找出每个人有多少的朋友,每两个朋友必须分在两个不同的组合,所以要分的组合即是最多的朋友集合的人数

#include<bits/stdc++.h>
using namespace std;

int pre[200005];
int sum[200005];
int n,m;

void Init(){
    
    
	for(int i=1;i<=n;i++){
    
    
		pre[i]=i;
		sum[i]=1;
	}
}

int Find(int x){
    
    
	if(pre[x]!=x){
    
    
		pre[x]=Find(pre[x]);
	}
	return pre[x];
}

void Join(int x,int y){
    
    
	int fx=Find(x),fy=Find(y);
	if(pre[fx]!=fy){
    
    
		pre[fx]=fy;
		sum[fy]+=sum[fx];
	}
}

int main(){
    
    
	cin>>n>>m;
	Init();
	for(int i=1;i<=m;i++){
    
    
		int x,y;
		scanf("%d%d",&x,&y);
		Join(x,y);
	}
	int ans=0;
	for(int i=1;i<=n;i++){
    
    
		ans=max(ans,sum[i]);
	}
	printf("%d",ans);
	return 0;
}

E.Coprime

题目链接

题解

按题意模拟即可

#include<bits/stdc++.h>
using namespace std;

int n;
int a[1000005];
int pre[1000005],tot=0;
int f[1000005];
int flag=0;

int Gcd(int a,int b){
    
    
	if(b==0)
		return a;
	return Gcd(b,a%b);
}

void SZS(){
    
    
	for(int i=2;i<=1000000;i++){
    
    
		if(!f[i]){
    
    
			pre[++tot]=i;
			for(int j=i+i;j<=1000000;j+=i)
				f[j]=1;
		}
	}
}

int main(){
    
    
	cin>>n;
	SZS();
//	for(int i=1;i<=tot;i++){
    
    
//		printf("%d ",pre[i]);
//	}
	memset(f,0,sizeof f);
	int G;
	for(int i=1;i<=n;i++){
    
    
		scanf("%d",&a[i]);
		int now=a[i];
		for(int j=1;j<=tot&&pre[j]<=sqrt(a[i]);j++){
    
    
			if(flag)	break;
			if(a[i]%pre[j]==0)
				f[pre[j]]++;
			if(f[pre[j]]>=2)	
				flag=1;
			while(a[i]%pre[j]==0){
    
    
				a[i]/=pre[j];
			}
		}
		if(a[i]>1){
    
    
			f[a[i]]++;
			if(f[a[i]]>=2)	flag=1;
		}	
		if(i==1)
			G=now;
		else{
    
    
			G=Gcd(now,G); 
		}
	}
	if(!flag&&G==1){
    
    
		printf("pairwise coprime");
	}
	else if(G==1){
    
    
		printf("setwise coprime");
	}
	else {
    
    
		printf("not coprime");
	}
	return 0;
}

F I hate Shortest Path Problem

题目链接

题解

定义一颗线段树t,维护第1行到第i行横着走的所需的最短距离;

定义now,表示从第一行能到达第 i行的列号的最小值。

假设当前的为i,如果now在l[i]到r[i]之间,且因为now是最小值,说明即使可以到达当前层,那么到达的列数也一定在r[i]的后面。既然无法通过上一层的l[i]~r[i]转移到当前层,索性将其全部变为无法取到的值。

如果now<l[i],说明对于l[i]以前的列是没有影响的,但在l[i]~r[i]的转换方式只能先到同一层的前面几列,再转换到l[i]到r[i]所对应的列。

如果now>r[i],则没有半毛钱影响。

#include<bits/stdc++.h>
using namespace std;
#define ll long long

struct Segment_Tree{
    
    
	int l,r;
	int ans;
	int add;
}t[800005];
int n,m;
const int INF=0x3f3f3f3f;

void Spread(int p){
    
    
	if(t[p].add){
    
    
		t[2*p].ans=t[p].l-t[p].add;
		t[2*p+1].ans=((t[p].l+t[p].r)>>1)+1-t[p].add;
		t[2*p].add=t[p].add;
		t[2*p+1].add=t[p].add;
		t[p].add=0;
	}
}

void Build_Tree(int p,int l,int r){
    
    
	t[p].l=l;
	t[p].r=r;
	t[p].ans=0;
	t[p].add=0;
	if(l==r)	return;
	int mid=(l+r)>>1;
	Build_Tree(p*2,l,mid);
	Build_Tree(p*2+1,mid+1,r);
}

void Change_Tree(int p,int l,int r,int val){
    
    
	if(l<=t[p].l&&t[p].r<=r){
    
    
		t[p].ans=t[p].l-val;
		t[p].add=val;
		return;
	}
	Spread(p);
	int mid=(t[p].r+t[p].l)>>1;
	if(l<=mid)
		Change_Tree(p*2,l,r,val);
	if(mid<r)
		Change_Tree(p*2+1,l,r,val);
	t[p].ans=min(t[p*2].ans,t[p*2+1].ans);
}

int Find_Tree(int p,int k){
    
    
	if(t[p].l==t[p].r)
		return k-t[p].ans;
	Spread(p);
	int mid=(t[p].l+t[p].r)>>1;
	if(k<=mid)
		return Find_Tree(p*2,k);
	else
		return Find_Tree(p*2+1,k);
}

int main(){
    
    
	cin>>n>>m;
	int now=1;
	Build_Tree(1,1,m);
	for(int i=1;i<=n;i++){
    
    
		int l,r;
		scanf("%d%d",&l,&r);
		if(now<l)
			Change_Tree(1,l,r,Find_Tree(1,l-1));
		else if(now>=l&&now<=r){
    
    
			Change_Tree(1,now,r,-INF);
			now=r+1;
		}
		if(now>m){
    
    
			printf("-1\n");
			continue;
		}
		printf("%d\n",i+t[1].ans);
	}
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/xf2056188203/article/details/112706097
Recomendado
Clasificación