Codeforces Round #544 (Div. 3) 全部题解

这次div3 虽然打得不是很好,但不过不是很难,都是很基础。

http://codeforces.com/contest/1133

A. Middle of the Contest

题意:给你两个时间,要求你输出两个时间的中点,这道题最简单的办法就是,吧时间全部转换为分,然后再转换为题目要求的表达,下面的代码没有用这种方法,写得有点臃肿。

#include<bits/stdc++.h>
using namespace std;
#define iofast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int N=2e5+10;
typedef long long ll;

int main()
{
    ///iofast;
    int a,b,c,d;
    scanf("%d:%d",&a,&b);
    scanf("%d:%d",&c,&d);
    if(a>c)
        swap(a,c),swap(b,d);
    int tmp=(c-a)*60+(d-b);
    tmp=tmp/2;
    int aa=tmp/60;
    int bb=tmp%60;
    a=a+aa;
    b=b+bb;
    while(b>=60)
        a+=1,b-=60;
    if(a<10)
        cout<<"0"<<a;
    else
        cout<<a;
    cout<<":";
    if(b<10)
        cout<<"0"<<b;
    else
        cout<<b;
    cout<<endl;
    return 0;
}

B. Preparation for International Women's Day

题意:给出n和k,接下来是n个数,问能从n个数中选出多少对数,其中每对数加起来能被k整除。

做法,每个数对k取模,并且记录下来个数,余数为i和k-i的数相加起来能被k整除。

#include<bits/stdc++.h>
using namespace std;
#define iofast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int N=2e5+10;
typedef long long ll;
int a[N],n,k,b[N];
map<int,int>mp;
int main()
{
    ///iofast;
    cin>>n>>k;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        b[i]=a[i]%k;
        mp[b[i]]++;
    }
    //sort(a+1,a+n+1);
    int ans=mp[0]/2*2;
    for(int i=1;i<k;i++)
    {

        if(i!=k-i)
        {
            int tmp=min(mp[i],mp[k-i]);
            ans+=tmp*2;
            mp[i]-=tmp;
            mp[k-i]-=tmp;

        }
        else
        {
            int tmp=mp[i];
            ans+=tmp/2*2;
            mp[i]=tmp/2*2;
        }
    }
    cout<<ans<<endl;
    return 0;
}

C. Balanced Team

题意:在n个数中k个数出来,其中最大值和最小值相差不应该超过5,问k的最大值;

做法,排序,然后对每一个数a[i]找到第一个比a[i]+5大的数的位置;

#include<bits/stdc++.h>
using namespace std;
#define iofast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int N=2e5+10;
typedef long long ll;
int a[N],n,k,b[N];
map<int,int>mp;
int main()
{
    ///iofast;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    sort(a+1,a+n+1);
    a[n+1]=1e9+10;
    int ans=1,tmp=1,mx=a[1],mr=1;
    for(int i=1;i<=n;i++)
    {
        int k=upper_bound(a+i,a+n+2,a[i]+5)-(a+i);
        //cout<<a[i+k]<<endl;
        ans=max(ans,k);
    }
    cout<<ans<<endl;
    return 0;
}

D. Zero Quantity Maximization

题意:给出两个数组,数组都大小为n,定义一个数组c  c[i]=d*a[i]+b[i],问选取合适的d,使数组c中为0的个数最大,求这个最大值

做法,用map 标记 pair,pair 保存 -a[i]和b[i]的最简形式,要求一个gcd,然后找到最大值。

#include<bits/stdc++.h>
using namespace std;
#define iofast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int N=2e5+10;
typedef long long ll;
int n,a[N],b[N];


int gcd(int a,int b)
{
    return b==0?a:gcd(b,a%b);
}

int main()
{
    ///iofast;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<=n;i++)
    {
        cin>>b[i];
    }
    map<pair<int,int>,int>mp;
    int cnt=0;
    pair<int,int> p1;
    for(int i=1;i<=n;i++)
    {
        if(a[i]==0&&b[i]!=0)
            continue;
        else if(a[i]==0&&b[i]==0)
            cnt++;
        else if(a[i]!=0&&b[i]==0)
            mp[make_pair(0,0)]++;
        else
        {
            int x=gcd(a[i],b[i]);
            p1.first=-b[i]/x;
            p1.second=a[i]/x;
            mp[p1]++;
        }
    }
    map<pair<int,int>,int>::iterator it;
    int ans=0;
    for(it=mp.begin();it!=mp.end();it++)
    {
        ans=max(ans,it->second);
    }
    cout<<ans+cnt<<endl;
    return 0;
}

E.K Balanced Teams

题意,给出n个数,和一个k,要求你从n个数中选出k组数,要求每组数的最大值和最小值相差不大于5.问最多能选多少个数。

这是一个dp题,dp[i][j]表示前i个人分为j组的最大值,当遇到第i个数时可以选取,可以要,如果要,m表示i后面比a[i]-5小的第一个数

dp[i][j]=max(dp[i-1][j],dp[m][j-1]+i-m);

#include<bits/stdc++.h>
using namespace std;
#define iofast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int N = 2e5 + 10;
typedef long long ll;
int n, k, a[N], b[N];
int dp[5010][5010];
int main()
{
	iofast;
	cin >> n >> k;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
	}
	if (k == n)
	{
		cout << n << endl;
		return 0;
	}
	sort(a + 1, a + n + 1);
	a[0] = -10;
	memset(dp, 0, sizeof(dp));
	int ans = 0;
	for (int i = 1; i <= n; i++)
	{
		int m = i;
		while (a[m] + 5 >= a[i])
		{
			m--;
		}
		for (int j = 1; j <= min(i, k); j++)
		{
			dp[i][j] = max(dp[i - 1][j], dp[m][j - 1] + i - m);
		}
	}
	for(int i = 1;i <= k; i++)
        ans = max(ans, dp[n][i]);
        cout << ans << endl;
	return 0;
}

F1. Spanning Tree with Maximum Degree

题目意思为,给出一个n个点,m条边的无向图,要求你求一颗所有顶点入度最大的生成树?

看了看样列猜了猜,直接写了一个找到入度最大的点然后开始BFS的代码居然过了??

#include<bits/stdc++.h>
using namespace std;
#define iofast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int N=2e5+10;
typedef long long ll;
int n,m,a[N],b[N];
int in[N],vis[N];
vector<int>g[N];
void bfs(int x)
{
    queue<int>qu;
    vis[x]=1;
    qu.push(x);
    while(!qu.empty())
    {
        int u=qu.front();
        qu.pop();
        for(int i=0;i<g[u].size();i++)
        {
            int v=g[u][i];
            if(vis[v])
                continue;
            cout<<u<<" "<<v<<endl;
            vis[v]=1;
            qu.push(v);
        }
    }
}
int main()
{
    memset(in,0,sizeof(in));
    memset(vis,0,sizeof(vis));
    cin>>n>>m;
    int u,v;
    for(int i=1;i<=m;i++)
    {
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
        in[u]++;
        in[v]++;
    }
    int maxn=0,mx=0;
    for(int i=1;i<=n;i++)
    {
        if(in[i]>maxn)
        {
            maxn=in[i];
            mx=i;
        }
    }
    bfs(mx);
    return 0;
}

F2. Spanning Tree with One Fixed Degree

题目意思为,给出一个n个点,m条边的无向图,还有一个d,叫你找到一个 使标号为1的点的度数为d的生成树,或者不存在。

这道题错了很多次。

做法:先用dfs找到图中连通量的个数以及其中与1相连的点,如果大于d则不存在,然后吧与1相连的点加入,然后进行一个bfs,但不过要注意与1相连的边怎么加,需要一定的技巧,我在这里错了很多次。

#include<bits/stdc++.h>
using namespace std;
#define iofast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int N = 2e5 + 10;
typedef long long ll;
vector<int>g[N];
int n,m,d,in[N],vis[N],tot;
int mr[N];
vector<int>one[N];
vector<int>ans1,ans2;
queue<int>qu;
void dfs(int u,int id)
{
    vis[u]=1;
    for(int i=0; i<g[u].size(); i++)
    {
        int v=g[u][i];
        if(vis[v])
            continue;
        if(v==1)
        {
            one[id].push_back(u);
            continue;
        }
        dfs(v,id);
    }
}

void bfs()
{
    while(!qu.empty())
    {
        int u=qu.front();
        qu.pop();
        for(int i=0; i<g[u].size(); i++)
        {
            int v=g[u][i];
            if(vis[v])
                continue;
            vis[v]=1;
            ans1.push_back(u);
            ans2.push_back(v);
            qu.push(v);
        }
    }
}
int main()
{
    iofast;
    memset(vis,0,sizeof(vis));
    memset(in,0,sizeof(in));
    memset(mr,0,sizeof(mr));
    cin>>n>>m>>d;
    int u,v;
    for(int i=1; i<=m; i++)
    {
        cin>>u>>v;
        in[u]++;
        in[v]++;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    int cnt=0;
    tot=0;
    if(in[1]<d)
    {
        cout<<"NO"<<endl;
        return 0;
    }
    for(int i=2; i<=n; i++)
    {
        if(!vis[i])
        {
            tot++;
            dfs(i,tot);
        }
    }
    if(tot>d)
    {
        cout<<"NO"<<endl;
        return 0;
    }
    memset(vis,0,sizeof(vis));
    vis[1]=1;
    for(int i=1; i<=tot; i++)
    {
        //cout<<one[i].size()<<endl;
        v=one[i][0];
        ans1.push_back(1);
        ans2.push_back(v);
        vis[v]=1;
        qu.push(v);
        cnt++;
    }
    for(int i=1; i<=tot&&cnt<d; i++)
    {
        for(int j=1; j<one[i].size()&&cnt<d; j++)
        {
            v=one[i][j];
            ans1.push_back(1);
            ans2.push_back(v);
            vis[v]=1;
            qu.push(v);
            cnt++;
        }
    }
    bfs();
    cout<<"YES"<<endl;
    for(int i=0; i<ans1.size(); i++)
    {
        cout<<ans1[i]<<" ";
        cout<<ans2[i]<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/KXL5180/article/details/88369740