• 牛客挑战赛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;
    }
    
  • 相关阅读:
    HDU多校第六场——HDU6638 Snowy Smile(线段树区间合并)
    java
    java
    java
    java
    java
    python
    appium
    python
    python
  • 原文地址:https://www.cnblogs.com/wzxbeliever/p/16305824.html
Copyright © 2020-2023  润新知