Codeforces Round #540 (Div. 3) A B C D1 D2 E F1题解

先上连接http://codeforces.com/contest/1118

A Water Buying

题意为叫你n升水,有两升一桶,一升一桶,分别给出价钱,叫你用最少钱的买水,题目不难,比较两种水,哪一种划算,最后如果剩了一升水,只能用一升一桶的,直接上代码

///#include<bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<set>
#include<stack>
using namespace std;
typedef long long ll;
const int N=400010;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll t;cin>>t;
    ll n,a,b;
    while(t--)
    {
        cin>>n>>a>>b;
        if(a<=b/2)
        {
            cout<<n*a<<endl;
        }
        else
        {
            cout<<b*(n/2)+a*(n%2)<<endl;
        }
    }
    return 0;
}

B Tanya and Candies

题意:给出n个数,你可以在里面去除一个,然后使奇数项的和等于偶数项,问这样的数一共有几个,直接处理前缀奇数偶数项和就可以了,然后枚举每一个数就可以了。

///#include<bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<set>
#include<stack>
using namespace std;
typedef long long ll;
const int N=200010;
int a[200010];
int l[N],r[N],sl[N],sr[N];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        if(i%2)
            l[i]=a[i];
        else
            r[i]=a[i];
        sl[i]=sl[i-1]+l[i];
        sr[i]=sr[i-1]+r[i];
    }
    int ans=0;
    int tmp1,tmp2;
    for(int i=1;i<=n;i++)
    {
        tmp1=sl[i-1],tmp2=sr[i-1];
        tmp2+=sl[n]-sl[i];
        tmp1+=sr[n]-sr[i];
        if(tmp1==tmp2)
            ans++;
    }
    cout<<ans<<endl;
    return 0;
}

C Palindromic Matrix

题意:给你n*n个数,问你是否能构成一个上下左右对称的矩阵,这道题模拟,偶数还好弄,奇数先做到出现4次或者4次多的数,记录下来,然后从下面的数中找出,还剩下2次及以上的数,最后一次的数,放的时候就放一个角,其他也如此放,正着放一次,反着放一次。

///#include<bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<set>
#include<stack>
#include<string>
#include<map>
using namespace std;
typedef long long ll;
const int N = 25;
int a[N*N];
int ans[N][N];
map<int, int>mp;
int main()
{
	memset(ans, 0, sizeof(ans));

	int n;
	cin >> n;
	int l = 1, r = 1;
	int cont = 0;
	for (int i = 1; i <= n*n; i++)
	{
		cin >> a[i];
		mp[a[i]]++;
		if (mp[a[i]] == 4 && cont != (n / 2)*(n / 2))
		{
			mp[a[i]] = 0;
			ans[l][r++] = a[i];
			cont++;
		}
		if (r>n/ 2)
		{
			l++; r = 1;
		}
	}
	if (n == 1)
	{
		puts("YES");
		cout << a[1] << endl;
		return 0;
	}
	int ttt[410], tmp = 0;
	memset(ttt, 0, sizeof(ttt));
	if (n % 2)
	{
		int tt;
		for (int i = 1; i <= n*n; i++)
		{
			if (mp[a[i]]>=2)
			{
				mp[a[i]] -= 2;
				ttt[++tmp] = a[i];
			}
		}
		for (int i = 1; i <= n*n; i++)
		{
			if (mp[a[i]] == 1)
			{
				tt = a[i];
				break;
			}
		}
		for (int i = 1; i <= n / 2; i++)
		{
			for (int j = 1; j <= (n) / 2; j++)
			{
				if (ans[i][j] == 0)
				{
					puts("NO");
					return 0;
				}
			}
		}
		for (int i = 1; i < n / 2 * 2; i++)
		{
			if (ttt[i] == 0)
			{
				{
					puts("NO");
					return 0;
				}
			}
		}
		puts("YES");
		int sss = 1;
		for (int i = 1; i <= n / 2; i++)
		{
			int j;
			for (j = 1; j <= n / 2; j++)
				cout << ans[i][j] << " ";
			cout << ttt[sss++] << " ";
			for (j = j - 1; j >= 1; j--)
				cout << ans[i][j] << " ";
			cout << endl;
		}
		for (int i = 1; i <= n / 2; i++)
			cout << ttt[sss++] << " ";
		cout << tt << " ";
		sss--;
		for (int i = n / 2; i >= 1; i--)
			cout << ttt[sss--] << " ";
		cout << endl;
		//sss = sss;
		for (int i = 1; i <= n / 2; i++)
		{
			int j;
			for (j = 1; j <= n / 2; j++)
				cout << ans[n / 2 - i + 1][j] << " ";
			cout << ttt[sss--] << " ";
			for (j = j - 1; j >= 1; j--)
				cout << ans[n / 2 - i + 1][j] << " ";
			cout << endl;
		}
	}
	else
	{
		for (int i = 1; i <= (n) / 2; i++)
		{
			for (int j = 1; j <= (n) / 2; j++)
			{
				if (ans[i][j] == 0)
				{
					puts("NO");
					return 0;
				}
			}
		}
		puts("YES");
		for (int i = 1; i <= n / 2; i++)
		{
			int j;
			for (j = 1; j <= (n + 1) / 2; j++)
				cout << ans[i][j] << " ";
			for (j = j - 1; j >= 1; j--)
				cout << ans[i][j] << " ";
			cout << endl;
		}
		for (int i = 1; i <= n / 2; i++)
		{
			int j;
			for (j = 1; j <= (n + 1) / 2; j++)
				cout << ans[n / 2 - i + 1][j] << " ";
			for (j = j - 1; j >= 1; j--)
				cout << ans[n / 2 - i + 1][j] << " ";
			cout << endl;
		}
	}
	return 0;
}

D1,D2 Coffee and Coursework 

 题意都一样的,只是数据范围不同,给出n个数,和一个m,一天之内可以选n个数,但不过除了第一数是原来的数,此后每一个数都要在,原来的基础上依次减去1,2,3.......,问我们最少多少天能选出来的得到的数加起来大于等于m.首先我们看到D1的数据比较小,答案,肯定在1到n之间,所以我们可以枚举天数得到答案,D2数据比较大,我们这样想如果a天完成了,那a+1天就一定能完成,因此我们采用二分的方法,逼近最小的天数,具体代码如下,注意细节:

///#include<bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<set>
#include<stack>
#include<string>
#include<map>
using namespace std;
typedef long long ll;
const int N=110;
ll n,m;
ll a[200010];
bool cmp(ll a,ll b)
{
    return a>b;
}
bool judge(ll i)
{
    if(i==0)
        return false;
    ll tmp=0,s=0;
    for(int j=1;j<=n;j++)
    {
        if(tmp>a[j])
            break;
        s+=a[j]-tmp;
        if(j%i==0)
            tmp++;
    }
    if(s>=m)
        return true;
    return false;
}
int main()
{
    cin>>n>>m;
    ll sum=0;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        sum+=a[i];
    }
    if(sum<m)
    {
        cout<<"-1"<<endl;
        return 0;
    }
    sort(a+1,a+n+1,cmp);
    ll l=1,r=n;
    ll ans;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(judge(mid)&&!judge(mid-1))
        {
            ans=mid;
            break;
        }
        if(judge(mid))
            r=mid-1;
        else
            l=mid+1;
    }
    cout<<ans<<endl;
    return 0;
}

E  Yet Another Ball Problem

题意:这道题实际上不是很难,给你两个数,n和k,题意叫你列出从1到k中选出2个数的排列,但不过这些排序的排序与摆放要满足题上的要求,直到摆放完n个位置,做法很简单,依次枚举,对每一个可以交换顺序在放一次。

///#include<bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<set>
#include<stack>
#include<string>
#include<map>
using namespace std;
typedef long long ll;
const int N=200010;
long long n,k;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>k;
    long long cnt=0;
    if(k*(k-1)<n)
    {
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i=1;i<=k-1;i++)
    {
        for(int j=i+1;j<=k;j++)
        {
            cout<<i<<" "<<j<<endl;
            cnt++;
            if(cnt!=n)
            {
                cout<<j<<" "<<i<<endl;
                cnt++;
            }
            if(cnt==n)
                return 0;
        }
    }
    return 0;
}

F1,Tree Cutting (Easy Version)

困难版本跨度太大,还不会,题意:给你一棵树,同时给出每个点的颜色,有三种,一种是红,一种是蓝色,一种是为染色,给出一个美丽的边的定义:删除那条边,剩下的两部分中,除去未染色,只能有一种颜色,做法也很暴力,先标记每一个结点的颜色情况,然后DFS任选一个根暴力搜索,更新每一个子树的颜色情况,同时判断连接的边是否满足条件。

///#include<bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<set>
#include<stack>
#include<string>
#include<map>
using namespace std;
typedef long long ll;
#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int N=300010;
vector<int>g[N];
int n,col[N][3],vis[N],ans,cnt1,cnt2;
void dfs(int x)
{
    vis[x]=1;
    for(int i=0;i<g[x].size();i++)
    {
        int v=g[x][i];
        if(!vis[v])
        {
            dfs(v);
            col[x][0]+=col[v][0];
            col[x][1]+=col[v][1];
            col[x][2]+=col[v][2];
        }
    }
    int p11=col[x][1],p12=col[x][2];
    int p21=cnt1-col[x][1],p22=cnt2-col[x][2];
    if(!(p11>0&&p12>0)&&!(p21>0&&p22>0)&&x!=1)
        ans++;
}
int main()
{
    FAST;
    cin>>n;
    int x;cnt1=cnt2=0;
    memset(col,0,sizeof(col));
    for(int i=1;i<=n;i++)
    {
        cin>>x;
        if(x==1)
            cnt1++;
        if(x==2)
            cnt2++;
        col[i][x]=1;
    }
    int u,v;
    for(int i=1;i<=n-1;i++)
    {
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    memset(vis,0,sizeof(vis));
    ans=0;
    dfs(1);
    cout<<ans<<endl;
    return 0;
}

猜你喜欢

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