1. 程式人生 > 其它 >牛客挑戰賽60

牛客挑戰賽60

比較簡單的簽到題

點選檢視程式碼
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
int T;
ll gcd(ll aa,ll bb){
	if(bb)return gcd(bb,aa%bb);
	return aa;
}
int main(){
	cin>>T; 
	while(T--){
		ll a,b;
		cin>>a>>b;
		ll gg=gcd(a,b);
		ll ag=a/gg,bg=b/gg;
		if(bg==1){
			cout<<2*a<<endl;
			continue;
		}
		for(ll i=2;;i++){
			if(gcd(i*ag,bg)==1){
			cout<<i*a<<endl;
			break;
		} 
		}
	}
     return 0;
}

心路歷程:k的範圍1e5 n方是一定不行的 但是正解就是列舉就好

分析:因為只是中點 所以座標裡面最多隻有2×1000 × 2×1000的點 並且題目要求只是出現兩次就可以結束

那麼最壞的情況這些點全部都出現一次 下一個點一定會出現兩次

所以直接暴力列舉就好 這個題的想法不得不說很牛

點選檢視程式碼
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int N = 1e6 + 10;
pii a[N];
int main()
{
    int t;
    scanf("%d",&t);
    while (t --)
    {
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        map<pii,int> mp;
        int  pos1 = -1,pos2 = -1;
        for(int i = 1;i <= k;i ++)
            scanf("%d%d",&a[i].first,&a[i].second);
        for(int i = 1;i <= k;i ++)
            for(int j = i + 1;j <= k;j ++)
            {
                mp[{a[i].first + a[j].first,a[i].second + a[j].second}] ++;
                if (mp[{a[i].first + a[j].first,a[i].second + a[j].second}] >= 2)
                {
                    pos1 = i;
                    pos2 = j;
                    goto cc;
                }
            }
cc:     if (~pos1)
        {
            double x = (a[pos1].first + a[pos2].first) * 1.0 / 2.0;
            double y = (a[pos1].second + a[pos2].second) * 1.0 / 2.0;
            printf("YES %.1lf %.1lf\n",x,y);
        }
        else puts("NO");
    }
    return 0;
}
點選檢視程式碼
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int mod=1e9+7;
int n;
int main(){
	cin>>n;
	ll ans=1;
	for(int i=1;i<=n;i++){
		ll x;scanf("%lld",&x);
		ans=ans*(i-x+1)%mod;
	}
	cout<<ans<<endl;
     return 0;
}

首先想到可以縮點 最後剩下一張拓撲圖 如果連通區域有多個 那麼一定無解

對於一個拓撲序唯一的 一定存在一個解 對於拓撲序不唯一的 也就是每次隊內元素>=2 一定是無解的

還有一個特別容易忽略的情況 那就是縮點後的強連通分量的大小為2 也就是有一個點對<a,b> 存在兩條邊a->b 和b->a

這樣任然無法滿足

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<math.h>
#include<vector>
#pragma comment(linker,"/STACK:1024000000,1024000000")
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const double eps=1e-6;
const int maxn=100000+10;
const int maxm=200000+10;
const int INF=1361474528;
 
struct{
    int to,w,next;
}edge[maxm];
int head[maxn],tot;
void Init(){
    tot=0;
    memset(head,-1,sizeof(head));
}
void addedge(int a,int b,int w){
    edge[tot].to=b;
    edge[tot].w=w;
    edge[tot].next=head[a];
    head[a]=tot++;
}
 
int dfn[maxn],low[maxn],scc[maxn],vis[maxn],stk[maxn],top,sccnum,indexx;
void tarjan(int x)
{
    if(dfn[x])return ;
    dfn[x]=++indexx;
    vis[x]=1;
    low[x]=dfn[x];
    stk[top++]=x;
    for(int i=head[x];i!=-1;i=edge[i].next)
    {
        int to=edge[i].to;
        if(!dfn[to]){
            tarjan(to);
            low[x]=min(low[x],low[to]);
        }
        else if(vis[to])low[x]=min(low[x],dfn[to]);
    }
    if(dfn[x]==low[x])
    {
        sccnum++;
        while(1)
        {
            int now=stk[--top];
            scc[now]=sccnum;
            vis[now]=0;
            if(now==x)break;
        }
    }
}
void get_scc(int n)
{
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    indexx=0;top=0;sccnum=0;
    for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
}
int du[maxn];
vector<int>v[maxn];
queue<int>q;
int num[maxn];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        Init();
        for(int i=0;i<maxn;i++)v[i].clear(),du[i]=0,num[i]=0;
        while(!q.empty())q.pop();
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            addedge(a,b,1);
        }
        get_scc(n);
        for(int i=1;i<=n;i++)
        {
            num[scc[i]]++;
            for(int j=head[i];j!=-1;j=edge[j].next)
            {
                int to=edge[j].to;
                if(scc[i]==scc[to])continue;
                du[scc[to]]++;
                v[scc[i]].push_back(scc[to]);
            }
        }
        int ok=1;
        for(int i=1;i<=sccnum;i++)if(num[i]==2)ok=0;
        for(int i=1;i<=sccnum;i++)
        {
            if(du[i]==0)q.push(i);
        }
        while(!q.empty())
        {
            int p=q.front();
            q.pop();
            if(!q.empty()){ok=0;break;}
            for(int to:v[p])
            {
                du[to]--;
                if(du[to]==0)q.push(to);
            }
        }
        if(ok)printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}