Codeforces Round #158 (Div. 2)

Solved: 3 out of 5

(First 3 problems) in a 2-hour contest, got contest rating 1660 (still in Div. 2 :-( )

Problem set: http://codeforces.com/contest/260

Suggested Solutions: http://codeforces.com/blog/entry/6263


Codeforces Round #158 (Div. 2) Tutorial

By  HolkinPV2 weeks ago, translation,  In English

260A - Adding Digits

At first try to add to the right one digit from 0 to 9. If it is impossible write -1. In other case, the remaining n–1 digits can be 0because divisibility doesn’t change.

260B - Ancient Prophesy

In this problem you have to consider every date from 2013 to 2015 year (there is no leap years in this interval), count occurrences of this date and find maximum. In one year there is 365 days, so the complexity of the solution (3·365·N).

260C - Balls and Boxes

Firstly describe simple solution. We will get by one ball from boxes (we begin from box x) from right to left (action back). At some moment there will be 0 balls in current box. This box is the first box in our initial problem (from which we took all balls and begun to put). In this box we put all balls, which we get from all boxes.

But we can’t solve the problem in such a way, because it is too long. Note, that before we meet the situation when in some box will be 0 balls, we will go through every element of array several times and subtract 1. So we can make our solution faster. We can subtract from every element of array minv - 1, where minv — minimum in array. After that you should doO(N) operations, that were mentioned above.

260D - Black and White Tree

The problem can be solved constructively maintaining the following invariant (rule) — the sum of the white vertices equals to the sum of the black vertices. The tree is a bipartite graph, so we build bipartite graph with no cycles, which will satisfy the conditions of the problem. Parts of graph will be black and white vertices.

On each step we will choose vertex v with minimum sum from white and black vertices. Then find any vertex of opposite coloru and add edge (u, v) with weight s[v], and subtract from sum of u sum of v, that is s[u] = s[u]–s[v]. After each step one vertex is deleted. That’s why there will be no cycles in constructed graph. When we delete last vertex of one of colors, all other vertices can be joined in any correct way with edges of weight 0.

260E - Dividing Kingdom

Consider 9! variants of location of integers a[i] on 9 areas. When we consider some location (some grid), we can easily find amount of cities to the left of the left vertical line, to the right of the right vertical line, below the lower horizontal line and above the upper horizontal line. All these numbers is sum of three values a[i].

We assume that the lines of the answer are always in half-integer coordinates. Then, knowing the above 4 numbers, we can uniquely determine separately for x and y how to accommodate all the 4 lines. It remains only to check that in all areas there is desired number of points.

For each of four zones (to the left of the left vertical line, to the right of the right vertical line, below the lower horizontal line and above the upper horizontal line) separately check, that all three areas have correct number of cities. It can be done offline using scan-line and segment-tree, which can find sum on interval and change value in some point. You should put all queries in some array, sort them and process from left to right. Note, when you check 8 from 9 areas for every 9! variants of location, the last area (central) could not be checked, it will be correct automatically.



My solutions for the first three problem:

#include <cstdio>
#include <cstdlib>

int main()
{
	int a,b,n;
	scanf("%d%d%d",&a,&b,&n);
	if(a*10%b==0)
	{
		printf("%d",a);
	}
	else if(b-a*10%b<10)
	{
		printf("%d%d",a,b-a*10%b);
		--n;
	}
	else
	{
		puts("-1");
		exit(0);
	}
	while(n--)
		putchar('0');	
	puts("");
	return 0;
}

260B - Ancient Prophesy
#include <cstdio>
#include <cstdlib>
#include <set>
#include <map>
#include <string>
#include <iostream>

using namespace std;

int main()
{
	const int dnum[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
	set<string> s;
	map<string,int> c;
	for(int y=2013;y<=2015;++y)
		for(int m=1;m<=12;++m)
			for(int d=1;d<=dnum[m];++d)
			{
				char buf[100];
				sprintf(buf,"%02d-%02d-%d",d,m,y);
				s.insert(string(buf));
			}
	string p;
	cin>>p;
	int mc=0;
	for(int i=0;i<p.length();++i)
	{
		string tmp=p.substr(i,10);
		if(s.find(tmp)!=s.end())
		{
			c[tmp]=c[tmp]+1;
			mc=max(mc,c[tmp]);
		}
	}
	for(map<string,int>::iterator i=c.begin();i!=c.end();++i)
		if(i->second == mc)
		{
			cout<<(i->first)<<endl;
			break;
		}
	return 0;
}

260C - Balls and Boxes
notice 64-bit integer
#include <cstdio>
#include <cstdlib>
#include <set>
#include <map>
#include <string>
#include <cstring>
#include <iostream>

using namespace std;

long long a[300000],b[300000];

int main()
{
	int n,x;
	memset(b,-1,sizeof(b));
	cin>>n>>x;
	--x;
	for(int i=0;i<n;++i)
		cin>>a[i];
	for(int i=0;i<n;++i)
		a[i+2*n]=a[i+n]=a[i];
	long long mina;
	int minx;
	minx=x+n,mina=a[x+n];
	for(int i=x+n-1;i>x;--i)
	{
		if(a[i]<mina)
			minx=i,mina=a[i];
	}
	b[minx]=n*mina+x+n-minx;
	for(int i=1;i<n;++i)
	{
		b[minx+i]=a[minx+i]-mina;
		if(minx+i<=n+x)
			--b[minx+i];
	}
	if(b[0]==-1)
		b[0]=(b[n]!=-1?b[n]:b[n*2]);
	cout<<b[0];
	for(int i=1;i<n;i++)
		cout<<" "<<(b[i]!=-1?b[i]:(b[i+n]!=-1?b[i+n]:b[i+n*2]));
	puts("");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值