A、
Cut Ribbon
Polycarpus has a ribbon, its length is n. He wants to cut the ribbon in a way that fulfils the following two conditions:
- After the cutting each ribbon piece should have length a, b or c.
- After the cutting the number of ribbon pieces should be maximum.
Help Polycarpus and find the number of ribbon pieces after the required cutting.
The first line contains four space-separated integers n, a, b and c (1 ≤ n, a, b, c ≤ 4000) — the length of the original ribbon and the acceptable lengths of the ribbon pieces after the cutting, correspondingly. The numbers a, b and c can coincide.
Print a single number — the maximum possible number of ribbon pieces. It is guaranteed that at least one correct ribbon cutting exists.
5 5 3 2
2
7 5 5 2
2
In the first example Polycarpus can cut the ribbon in such way: the first piece has length 2, the second piece has length 3.
In the second example Polycarpus can cut the ribbon in such way: the first piece has length 5, the second piece has length 2.
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define ll long long
using namespace std;
int n,a[3];
int main() {
while(~scanf("%d%d%d%d",&n,&a[0],&a[1],&a[2])){
int ans=-1;
sort(a,a+3);
if(a[0]==1 || a[1]==1 || a[2]==1){
printf("%d\n",n);
continue ;
}
if(n % a[0] == 0){
printf("%d\n",n/a[0]);
continue ;
}
for(int i=0;i<=n/a[0];i++){
for(int j=0;j<=n/a[1];j++){
if( i*a[0]+j*a[1] <=n && ( n-i*a[0]-j*a[1] ) % a[2] == 0 ){
ans=max(ans,i+j+( ( n-i*a[0]-j*a[1] ) / a[2] ));
}
}
}
printf("%d\n",ans);
}
return 0;
}
B、
s-palindrome
Let's call a string "s-palindrome" if it is symmetric about the middle of the string. For example, the string "oHo" is "s-palindrome", but the string "aa" is not. The string "aa" is not "s-palindrome", because the second half of it is not a mirror reflection of the first half.
You are given a string s. Check if the string is "s-palindrome".
The only line contains the string s (1 ≤ |s| ≤ 1000) which consists of only English letters.
Print "TAK" if the string s is "s-palindrome" and "NIE" otherwise.
oXoxoXo
TAK
bod
TAK
ER
NIE
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <map>
#define ll long long
using namespace std;
char s[1005];
map<char,char> mp;
void INIT(){
mp['A']='A';
mp['b']='d';
mp['d']='b';
mp['H']='H';
mp['I']='I';
/*mp['i']='i';*//*?????*/
/*mp['J']='L';
mp['L']='J';*/
/*mp['l']='l';*/
mp['M']='M';
/*mp['m']='m';*/
/*mp['n']='n';*/
mp['O']='O';
mp['o']='o';
mp['p']='q';
mp['q']='p';
/*mp['S']='Z';
mp['s']='z';*/
mp['T']='T';
mp['U']='U';
mp['u']='u';
mp['V']='V';
mp['v']='v';
mp['W']='W';
mp['w']='w';
mp['X']='X';
mp['x']='x';
mp['Y']='Y';
/*mp['Z']='S';
mp['z']='s';*/
}
int main() {
INIT();
while(~scanf("%s",s)){
int len=strlen(s);
int i=0,j=len-1;
int flag=1;
while(i <= j){
if(mp[s[i]]==NULL || mp[ s[i] ] != s[j]){
flag=0;
break ;
}
i++;
j--;
}
if(flag) printf("TAK\n");
else printf("NIE\n");
}
return 0;
}
C、
Mahmoud and Ehab and the bipartiteness
Mahmoud and Ehab continue their adventures! As everybody in the evil land knows, Dr. Evil likes bipartite graphs, especially trees.
A tree is a connected acyclic graph. A bipartite graph is a graph, whose vertices can be partitioned into 2 sets in such a way, that for each edge (u, v) that belongs to the graph, u and v belong to different sets. You can find more formal definitions of a tree and a bipartite graph in the notes section below.
Dr. Evil gave Mahmoud and Ehab a tree consisting of n nodes and asked them to add edges to it in such a way, that the graph is still bipartite. Besides, after adding these edges the graph should be simple (doesn't contain loops or multiple edges). What is the maximum number of edges they can add?
A loop is an edge, which connects a node with itself. Graph doesn't contain multiple edges when for each pair of nodes there is no more than one edge between them. A cycle and a loop aren't the same .
The first line of input contains an integer n — the number of nodes in the tree (1 ≤ n ≤ 105).
The next n - 1 lines contain integers u and v (1 ≤ u, v ≤ n, u ≠ v) — the description of the edges of the tree.
It's guaranteed that the given graph is a tree.
Output one integer — the maximum number of edges that Mahmoud and Ehab can add to the tree while fulfilling the conditions.
3 1 2 1 3
0
5 1 2 2 3 3 4 4 5
2
Tree definition: https://en.wikipedia.org/wiki/Tree_(graph_theory)
Bipartite graph definition: https://en.wikipedia.org/wiki/Bipartite_graph
In the first test case the only edge that can be added in such a way, that graph won't contain loops or multiple edges is (2, 3), but adding this edge will make the graph non-bipartite so the answer is 0.
In the second test case Mahmoud and Ehab can add edges (1, 4) and (2, 5).
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#define ll long long
using namespace std;
const int maxn=1e5+10;
int n;
vector<int> u[10*maxn];
int num0,num1;
int vis[maxn];
void dfs(int x,int step){
int len=u[x].size();
for(int i=0;i<len;i++){
if(!vis[ u[x][i] ]){
if(step % 2 == 0) num1++;
else num0++;
vis[ u[x][i] ] = 1;
dfs(u[x][i],step+1);
}
}
}
int main(){
scanf("%d",&n);
int t1,t2;
for(int i=0;i<n-1;i++){
scanf("%d%d",&t1,&t2);
u[t1].push_back(t2);
u[t2].push_back(t1);
}
vis[1]=1;
num0=1;
num1=0;
dfs(1,0);
printf("%I64d\n",(ll)num0*(ll)num1-n+1);
return 0;
}
D、Dasha and Very Difficult Problem
Dasha logged into the system and began to solve problems. One of them is as follows:
Given two sequences a and b of length n each you need to write a sequence c of length n, the i-th element of which is calculated as follows: ci = bi - ai.
About sequences a and b we know that their elements are in the range from l to r. More formally, elements satisfy the following conditions: l ≤ ai ≤ r and l ≤ bi ≤ r. About sequence c we know that all its elements are distinct.
Dasha wrote a solution to that problem quickly, but checking her work on the standard test was not so easy. Due to an error in the test system only the sequence a and the compressed sequence of the sequence c were known from that test.
Let's give the definition to a compressed sequence. A compressed sequence of sequence c of length n is a sequence p of length n, so that pi equals to the number of integers which are less than or equal to ci in the sequence c. For example, for the sequence c = [250, 200, 300, 100, 50] the compressed sequence will be p = [4, 3, 5, 2, 1]. Pay attention that in c all integers are distinct. Consequently, the compressed sequence contains all integers from 1 to n inclusively.
Help Dasha to find any sequence b for which the calculated compressed sequence of sequence c is correct.
The first line contains three integers n, l, r (1 ≤ n ≤ 105, 1 ≤ l ≤ r ≤ 109) — the length of the sequence and boundaries of the segment where the elements of sequences a and b are.
The next line contains n integers a1, a2, ..., an (l ≤ ai ≤ r) — the elements of the sequence a.
The next line contains n distinct integers p1, p2, ..., pn (1 ≤ pi ≤ n) — the compressed sequence of the sequence c.
If there is no the suitable sequence b, then in the only line print "-1".
Otherwise, in the only line print n integers — the elements of any suitable sequence b.
5 1 5 1 1 1 1 1 3 1 5 4 2
3 1 5 4 2
4 2 9 3 4 8 9 3 2 1 4
2 2 2 9
6 1 5 1 1 1 1 1 1 2 3 5 4 1 6
-1
Sequence b which was found in the second sample is suitable, because calculated sequence c = [2 - 3, 2 - 4, 2 - 8, 9 - 9] = [ - 1, - 2, - 6, 0] (note that ci = bi - ai) has compressed sequence equals to p = [3, 2, 1, 4].
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#define ll long long
using namespace std;
const int maxn=1e5+10;
ll n,l,r;
struct node{
ll a,p,b,c,inde;
}nn[maxn];
bool cmp(node A,node B){
return A.p < B.p;
}
bool cmp1(node A,node B){
return A.inde < B.inde;
}
int main(){
scanf("%d",&n);
scanf("%d%d",&l,&r);
for(int i=0;i<n;i++){
scanf("%d",&nn[i].a);
nn[i].inde=i;
}
for(int i=0;i<n;i++) scanf("%d",&nn[i].p);
sort(nn,nn+n,cmp);
nn[0].b=l;
nn[0].c=nn[0].b-nn[0].a;
int flag=1;
for(int i=1;i<n;i++){
nn[i].c=nn[i-1].c+1;
nn[i].b=nn[i].c+nn[i].a;
if(nn[i].b <l){
nn[i].b = l;
nn[i].c=nn[i].b-nn[i].a;
}
if(nn[i].b > r){
flag=0;
break ;
}
}
if(!flag) printf("-1\n");
else{
sort(nn,nn+n,cmp1);
printf("%d",nn[0].b);
for(int i=1;i<n;i++) printf(" %d",nn[i].b);
printf("\n");
}
return 0;
}
E、
Energy exchange
It is well known that the planet suffers from the energy crisis. Little Petya doesn't like that and wants to save the world. For this purpose he needs every accumulator to contain the same amount of energy. Initially every accumulator has some amount of energy: the i-th accumulator has ai units of energy. Energy can be transferred from one accumulator to the other. Every time x units of energy are transferred (x is not necessarily an integer) k percent of it is lost. That is, if xunits were transferred from one accumulator to the other, amount of energy in the first one decreased by x units and in other increased by units.
Your task is to help Petya find what maximum equal amount of energy can be stored in each accumulator after the transfers.
First line of the input contains two integers n and k (1 ≤ n ≤ 10000, 0 ≤ k ≤ 99) — number of accumulators and the percent of energy that is lost during transfers.
Next line contains n integers a1, a2, ... , an — amounts of energy in the first, second, .., n-th accumulator respectively (0 ≤ ai ≤ 1000, 1 ≤ i ≤ n).
Output maximum possible amount of energy that can remain in each of accumulators after the transfers of energy.
The absolute or relative error in the answer should not exceed 10 - 6.
3 50 4 2 1
2.000000000
2 90 1 11
1.909090909
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=10000+10;
int n,k;
double a[maxn];
int main(){
while(~scanf("%d%d",&n,&k)){
for(int i=0;i<n;i++){
scanf("%lf",&a[i]);
}
sort(a,a+n);
double l=a[0],r=a[n-1];
double mid=(l+r)/2.0;
while(r-l > 1e-6){
double sum=0;
for(int i=0;i<n;i++){
if(a[i] > mid) sum+=(a[i]-mid)-(a[i]-mid)*k/100;
else sum-=(mid-a[i]);
}
if(sum < -1e-6) r=mid;
else if(sum > 1e-6) l=mid;
else break;
mid=(l+r)/2.0;
}
printf("%.9lf\n",mid);
}
return 0;
}
F - Roads not only in Berland
Berland Government decided to improve relations with neighboring countries. First of all, it was decided to build new roads so that from each city of Berland and neighboring countries it became possible to reach all the others. There are n cities in Berland and neighboring countries in total and exactly n - 1 two-way roads. Because of the recent financial crisis, the Berland Government is strongly pressed for money, so to build a new road it has to close some of the existing ones. Every day it is possible to close one existing road and immediately build a new one. Your task is to determine how many days would be needed to rebuild roads so that from each city it became possible to reach all the others, and to draw a plan of closure of old roads and building of new ones.
The first line contains integer n (2 ≤ n ≤ 1000) — amount of cities in Berland and neighboring countries. Next n - 1 lines contain the description of roads. Each road is described by two space-separated integers ai, bi (1 ≤ ai, bi ≤ n, ai ≠ bi) — pair of cities, which the road connects. It can't be more than one road between a pair of cities. No road connects the city with itself.
Output the answer, number t — what is the least amount of days needed to rebuild roads so that from each city it became possible to reach all the others. Then output t lines — the plan of closure of old roads and building of new ones. Each line should describe one day in the format i j u v — it means that road between cities iand j became closed and a new road between cities u and v is built. Cities are numbered from 1. If the answer is not unique, output any.
2 1 2
0
7 1 2 2 3 3 1 4 5 5 6 6 7
1 3 1 3 7
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1000+10;
int pre[maxn];
int vis[maxn];
int poit[maxn];
int n;
int unionSearch(int root){
int son,tmp;
son=root;
while(root != pre[root])
root=pre[root];
while(son != root){
tmp=pre[son];
pre[son]=root;
son=tmp;
}
}
struct node{
int x,y;
}nn[maxn];
int main(){
scanf("%d",&n);
for(int i=0;i<=n;i++){
pre[i]=i;
}
int a,b;
int cnt=0;
int ans=0;
for(int i=0;i<n-1;i++){
scanf("%d%d",&a,&b);
int x=unionSearch(a);
int y=unionSearch(b);
if(x != y){
pre[x]=y;
}
else{
nn[++cnt].x=a;
nn[cnt].y=b;
ans++;
}
}
cnt=0;
for(int i=1;i<=n;i++){
if(unionSearch(i) == i){
poit[ ++cnt ]=i;
}
}
printf("%d\n",ans);
for(int i=1;i<=ans;i++){
printf("%d %d %d %d\n",nn[i].x,nn[i].y,poit[i],poit[i+1]);
}
return 0;
}