现在的位置: 首页 > 综合 > 正文

Codeforces Round #274 (Div. 2)

2017年12月16日 ⁄ 综合 ⁄ 共 4302字 ⁄ 字号 评论关闭

A:链接:http://codeforces.com/contest/479/problem/A 

分析:把所有可能都尝试一遍就可以了。。。。

代码:

#include <iostream>
#include <algorithm>
#include <string.h>
#include <iomanip>
#include <map>
#include <vector>
#include <math.h>
#include <string>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const int N=100020;

int ans[N];
ll arr[N];
int n,m,k,a,r,g,b,c;
string s1,s2;

int main()
{
        
    while(cin>>a>>b>>c)
    {
        int ans = 0;
        ans = max(ans,a+b+c);
        ans = max(ans,a*b*c);
        ans = max(ans,a+b*c);
        ans = max(ans,(a+b)*c);
        ans = max(ans,a*b+c);
        ans = max(ans,a*(b+c));
        cout<<ans<<endl;
        
    }
            
    return 0;

}

B题,链接:http://codeforces.com/contest/479/problem/B
分析:因为数据不大,故可以每次都排序,然后将最大的减一,最小的加一,知道最大的和最小的相差不过1

代码:

#include <iostream>
#include <algorithm>
#include <string.h>
#include <iomanip>
#include <map>
#include <vector>
#include <math.h>
#include <string>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const int N=100020;

int ans[N];
ll arr[N];
int n,m,k,a,r,g,b,c;
string s1,s2;

int main()
{
        
    while(cin>>n>>m)
    {
        vector<pair<int,int> > v;
        for(int i=1;i<=n;i++)
        {
            cin>>a;
            v.push_back(make_pair(a,i));
        }
        int cnt = 0;
        vector<pair<int,int> > ans;
        while(cnt<m)
        {
            sort(v.begin(),v.end());
            int diff = v[v.size()-1].first-v[0].first;
            if(diff==0||diff==1)
            {
                break;
            }
            else
            {
                ans.push_back(make_pair(v[v.size()-1].second,v[0].second));
                v[v.size()-1].first--;
                v[0].first++;
                cnt++;
            }
        }
        sort(v.begin(),v.end());
        int diff = v[v.size()-1].first-v[0].first;
        cout<<diff<<" "<<ans.size()<<endl;
        for(int i=0;i<ans.size();i++)
            cout<<ans[i].first<<" "<<ans[i].second<<endl;
    }
            
    return 0;

}

c题,链接:http://codeforces.com/contest/479/problem/c

分析:题目读了半天,感觉题目写的有点问题。。。。意思是不管你选哪天来考试,它都会记录ai来当作record,这样便可以根据ai来排序,然后每次能选bi就选bi,不行就选ai

代码:

#include <iostream>
#include <algorithm>
#include <string.h>
#include <iomanip>
#include <map>
#include <vector>
#include <math.h>
#include <string>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const int N=100020;

int ans[N];
ll arr[N];
int n,m,k,a,r,g,b,c;
string s1,s2;

int main()
{
		
	while(cin>>n)
	{
		vector<pair<int,int> > v;
		for(int i=0;i<n;i++)
		{
			cin>>a>>b;
			v.push_back(make_pair(a,b));
		}
		sort(v.begin(),v.end());
		int ans = 0;
		for(int i=0;i<v.size();i++)
		{
			if(i==0)
				ans = v[i].second;
			else
			{
				if(v[i].second>=v[i-1].second)
				{
					if(v[i].second>=ans)
						ans = v[i].second;
					else
						ans = v[i].first;
				}
				else
					ans = v[i].first;
			}
		}
		cout<<ans<<endl;
	}
			
	return 0;

}

D题:链接:http://codeforces.com/contest/479/problem/D

分析:因为0和l是肯定有的,所以答案不会超过2个,故可以先判断x和y是否都能被检测出来,如果两个都可以的话,返回0,只有一个可以的话,那么直接返回那一个,反正总是要加一个的,而若是两个都没有的话,则看能不能通过加一个的方法来满足测两个的要求,不行的话就返回x,y两个。

代码:

#include <iostream>
#include <algorithm>
#include <string.h>
#include <iomanip>
#include <map>
#include <vector>
#include <math.h>
#include <string>
#include <set>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const int N=100020;

int ans[N];
int arr[N];
int n,m,k,a,r,g,b,c,l,x,y;
string s1,s2;
set<int> s;
int canFind(int x)
{
	for(int i=0;i<n;i++)
	{
		if(s.count(arr[i]-x))
			return 1;
	}
	return 0;
}
int find()
{
	for(int i=0;i<n;i++)
	{
		if(arr[i]+x>=0&&arr[i]+x<=l&&s.count(arr[i]+x+y)>0)
			return arr[i]+x;
		if(arr[i]-x>=0&&arr[i]-x<=l&&s.count(arr[i]-x+y)>0)
			return arr[i]-x;
		if(arr[i]+x>=0&&arr[i]+x<=l&&s.count(arr[i]+x-y)>0)
			return arr[i]+x;
		if(arr[i]-x>=0&&arr[i]-x<=l&&s.count(arr[i]-x-y)>0)
			return arr[i]-x;
	}
	return -1;
}
int main()
{
		
	while(cin>>n>>l>>x>>y)
	{
		s.clear();
		for(int i=0;i<n;i++)
		{
			cin>>arr[i];
			s.insert(arr[i]);
		}
		int t1 = canFind(x);
		int t2 = canFind(y);
		if(t1&&t2)
			cout<<0<<endl;
		else if(t1&&!t2)
			cout<<1<<endl<<y<<endl;
		else if(!t1&&t2)
			cout<<1<<endl<<x<<endl;
		else
		{
			int p = find();
			if(p==-1)
			{
				cout<<2<<endl;
				cout<<x<<" "<<y<<endl;
			}
			else
			{
				cout<<1<<endl;
				cout<<p<<endl;
			}
		}
	}
			
	return 0;

}

E题,链接:http://codeforces.com/contest/479/problem/E

分析:很显然是个dp问题,但是我只能想到dp[k][i][j]来表示第k次走到i这个位置,来源是j,这样的话是肯定可以算的,但是由于N=5000,肯定会超时。。。但是观察其实可以发现,若当前位置为i,则可以走到i这个位置的点其实是一条连续的线段,而在计算i这个点的时候,我们需要的是这条线段的和,故可以利用前缀和的方法,每次用O(1)的时间来计算出线段和,从而整个算法的复杂度为O(KN),同时需要注意的是,若a<b,则永远不可能跑到b上面去,反之则永远不可能跑到b下面去,这点在计算线段的位置比较有用

代码:

#include <iostream>
#include <algorithm>
#include <string.h>
#include <iomanip>
#include <map>
#include <vector>
#include <math.h>
#include <string>
#include <set>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const int N=100020;
ll dp[2][N];
ll f[N];

int ans[N];
int arr[N];
int n,m,k,a,r,g,b,c,l,x,y;
string s1,s2;

int main()
{
        
    while(cin>>n>>a>>b>>k)
    {
        memset(dp,0,sizeof(dp));
        memset(f,0,sizeof(f));
        dp[0][a]=1;
        int now = 0;
        int pre = 1;
        for(int i=1;i<=k;i++)
        {
            now^=1;
            pre^=1;
            for(int j=1;j<=n;j++)
            {
                f[j] = f[j-1]+dp[pre][j];
            }
            for(int j=1;j<=n;j++)
            {
                int l,r;
                if(j < b) l=1, r=(b+j+1)/2-1;
                else if(j>b) l=(b+j)/2+1, r=n;
                else
                    continue;
                dp[now][j] = (f[r]-f[l-1]-dp[pre][j]+mod)%mod;
            }
        }
        ll ans = 0;
        for(int j=1;j<=n;j++)
            ans = (ans+dp[now][j])%mod;
        cout<<ans<<endl;
        
    }
            
    return 0;

}

抱歉!评论已关闭.