牛客练习赛43(A B C F解题报告)

版权声明:欢迎转载,转载请注明出处,如有错误,还望指出,谢谢 博客地址:https://blog.csdn.net/lanyanzhiji123asd https://blog.csdn.net/lanyanzhiji123asd/article/details/89072212

比赛链接:https://ac.nowcoder.com/acm/contest/548#question

A:

暴力就行的,注意输出

#include<bits/stdc++.h>
using namespace std;
struct node
{
    int a,b;
}mp[105];
int main()
{
    int n,i,a,b,flag,j;
    while(cin>>n)
    {
        flag=0;
        for(i=0;i<n;i++)
        {
            cin>>mp[i].a>>mp[i].b;
        }
        for(i=0;i<n&&!flag;i++)
        {
            for(j=i+1;j<n&&!flag;j++)
            {
                if(mp[i].a==mp[j].a+mp[j].b&&mp[j].a==mp[i].a+mp[i].b)
                    flag=1;
            }
        }
        if(flag)    cout<<"YE5"<<endl;
        else cout<<"N0"<<endl;
    }
     
     
    return 0;
 }

B:

如果我们要求n/m 小数点后面的数

那么按照除法的话,先求出temp=n%m;

然后temp*10/m   就是小数点后面的第一位数;

然后temp=temp*10%m;

temp*10/m 就是小数点后面第二位数

这样不断迭代下去

要求k1-k2之间的小数,所以我先把n%m扩大10^k1倍就行

再用下快速幂,注意一下边界就行的

#include<bits/stdc++.h>
using namespace std;
#define ll long long
 
ll qpow(ll a, ll b,ll mod)
{//cout<<a<<" "<<b<<" "<<mod<<endl;
    ll res=1;
     
    while(b)
    {
        if(b%2!=0)
        {
            res*=a;
            res%=mod;
//          cout<<res<<endl;
        }
        a*=a;
        a%=mod;
        b/=2;
    }
//  cout<<res<<endl;
    return res;
      
}
 
int main()
{
    ll n,m,k1,k2;
    int i;
    int t;
    cin>>t;
    while(t--)
    {cin>>m>>n>>k1>>k2;
        ll temp=qpow(10,k1-1,n);
//      cout<<temp<<endl;
        temp=(m%n)*temp;
        temp%=n;
        for(i=k1;i<=k2;i++)
        {
            temp*=10;
            cout<<temp/n;
            temp%=n;
        }
        cout<<endl;
    }
     
     
    return 0;
 }

C:

这道题很卡时间

试了十多发才AC

先设置一个虚拟节点 0 吧 所有的节点和0有一条路,权重就是学习这个知识点花费的时间

然后有些节点之间会有路,权重;

所有已学过的知识点和0一起构成了一个联通的

最后求下最小生成树

#include <iostream>
#include <vector>
#include <string.h>
#include <queue>
#include <algorithm>
#define pii pair<int,int>
#define ll long long int
using namespace std;
const int maxn = 7e6 + 100;
ll ans = 0;
ll n,m,k,t;
int cnt = 0;
inline int read()
{
    ll x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*f;
}
int f[maxn];
int find(int x)
{
    if(x == f[x])
        return x;
    f[x] = find(f[x]);
    return f[x];
}
  
struct EGE
{
    int from,to,w;
    bool friend operator < (EGE a,EGE b)
    {
        return a.w<b.w;
    }
};
EGE edge[maxn];
  
void krusal()
{
    int road = k;
    for(int i=0;i<cnt;i++)
    {
        int fx = find(edge[i].from);
        int fy = find(edge[i].to);
        if(fx == fy)
            continue;
        f[fx]=fy;
        ans += edge[i].w;
        road++;
        if(road == n || ans>t)
            break;
    }
}
  
int main(int argc, const char * argv[]) {
      
    int x,y,z;
    int tmp;
    n = read();
    m = read();
    k = read();
    t = read();
    f[0] = 0;
      
    for(int i=1;i<=n;i++)
    {
        f[i] = i;
        tmp = read();
        edge[cnt].from = 0;
        edge[cnt].to = i;
        edge[cnt].w = tmp;
        cnt++;
    }
    for(int i=1;i<=k;i++)
    {
        tmp = read();
        f[tmp]=0;
    }
    for(int i=1;i<=m;i++)
    {
        x = read(); y = read(); z = read();
        edge[cnt].from = x;
        edge[cnt].to = y;
        edge[cnt].w = z;
        cnt++;
    }
    sort(edge,edge+cnt);
      
    krusal();
    if(ans > t)
        printf("No");
    else
        printf("Yes");
    return 0;
}

D:

裸的容斥定理

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<set>
#include<queue>
using namespace std;
#define ll long long
int prim[]={2,3,5,7,11,13,17,19};
int main()
{
 	std::ios::sync_with_stdio(false);
	int t,num,cnt,i,j;
	ll k,q,n,m,temp,ans;
	cin>>t;
	while(t--)
	{
		
		cin>>k>>q>>n>>m;
		ans=n;
		if(k==0)
		{
			cout<<"QAQ"<<endl;
			continue;
		}
		for(cnt=0;cnt<8;cnt++)
		{
			if(m<prim[cnt])
				break;
		}
		//二进制枚举,一共有cnt个素数,这cnt个素数自由组合,然后我就判断每个素数在不在
		//里面,最后判断有奇数个素数还是偶数个素数,奇加偶减~ 
		for(i=1;i<(1<<cnt);i++) 
		{
			num=0;
			temp=1;
			for(j=0;j<cnt;j++)
			{
				if(i&(1<<j))
				{
					num++;
					temp*=prim[j];
				}
			}
			if(num&1)
			{
				ans-=n/temp;
			}
			else
			{
				ans+=n/temp;
			}
		}
//		cout<<ans<<endl;
		if(ans+k>=q)
			cout<<"Yes"<<endl;
		else
		{
			cout<<"QAQ"<<endl;
		}
	}

 return 0;
}

猜你喜欢

转载自blog.csdn.net/lanyanzhiji123asd/article/details/89072212