【LDU】2018个人PK赛#5

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 ab 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.

Input

The first line contains four space-separated integers nab 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 ab and c can coincide.

Output

Print a single number — the maximum possible number of ribbon pieces. It is guaranteed that at least one correct ribbon cutting exists.

Example
Input
5 5 3 2
Output
2
Input
7 5 5 2
Output
2
Note

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.

题意:给你一条丝带,问你可以分的方案数,整洁我觉得是完全背包,不过暴力就可以过(一个意思吧)
My ugly code
#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.

English alphabet

You are given a string s. Check if the string is "s-palindrome".

Input

The only line contains the string s (1 ≤ |s| ≤ 1000) which consists of only English letters.

Output

Print "TAK" if the string s is "s-palindrome" and "NIE" otherwise.

Example
Input
oXoxoXo
Output
TAK
Input
bod
Output
TAK
Input
ER
Output
NIE
这个题才神坑呢,S和Z竟然不是镜面、、、颠覆了我的三观
My ugly code
#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 .

Input

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 ≤ nu ≠ v) — the description of the edges of the tree.

It's guaranteed that the given graph is a tree.

Output

Output one integer — the maximum number of edges that Mahmoud and Ehab can add to the tree while fulfilling the conditions.

Example
Input
3
1 2
1 3
Output
0
Input
5
1 2
2 3
3 4
4 5
Output
2
Note

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).

题意:让你弄出来一个二分图,他给了你那些点的两两相连,你把这些点分开,然后去把两个集合内所有的点都两两相连,求需要新加多少条边。
分析:如果第一个集合内有a个点,第二个集合内有b个点,那么最多有a*b条边,需要新加a*b-n条,然后就可以解决了,用dfs搜索出来其中一个集合有多少个点(幷查集也可以),然后计算就可以了 
dfs的策略是,只要是跟他相连的,肯定不能和他在同一个集合
My ugly code
#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.

Input

The first line contains three integers nlr (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.

Output

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.

Example
Input
5 1 5
1 1 1 1 1
3 1 5 4 2
Output
3 1 5 4 2 
Input
4 2 9
3 4 8 9
3 2 1 4
Output
2 2 2 9 
Input
6 1 5
1 1 1 1 1 1
2 3 5 4 1 6
Output
-1
Note

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].

题意:这里有一个式子c=b-a,还有一个p数组,是对c数组求出来以后进行了离散化以后的,现在给你p和a数组,让你求出来b数组,其实很简单。
用结构体,把a,b,c,p都放在里面,再放一个index,记录最原始的顺序,先按p排序,一个个算出c的取值,c还必须大于l,所有的c不相等,如果可以凑出来c,然后你在去求b,之后输出就可以了
My ugly code
#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.

Input

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

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.

Example
Input
3 50
4 2 1
Output
2.000000000
Input
2 90
1 11
Output
1.909090909
就是让你把给你的一排数,让你把他们平均成差不多大小(相差在1e6),然后如果把a里面的数转移给b一部分,那么就要承担百分之k的损失;
一开始看到这个题,唉呀妈呀,这怎么过,都转成多大的,后来想想,只能一个个去试,那么就是二分着试,先假设是转化成(最大值+最小值)/2,然后去试试,大于这个值的肯定转移给其他人,小于这个值的肯定接受其他人的转,看看转完之后 是不是正好,正好,就break,否则,调整最大最小值,在试试,最后一点点逼近
My ugly code
#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.

Input

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 aibi (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

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.

Example
Input
2
1 2
Output
0
Input
7
1 2
2 3
3 1
4 5
5 6
6 7
Output
1
3 1 3 7
题意:给你n个国家,以及n-1条路,让你去掉循环,把这些国家连起来
思路:幷查集,如果给的这两条边已经有相同的“领导”了,再加上他肯定会存在循环,那么就准备删除他就可以,肯定还需要把不在一个“领导集团”下面的链接起来,然后就可以了
不会幷查集的可以看一下下面这个博客(http://blog.csdn.net/niushuai666/article/details/6662911
My ugly code
#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;
}












  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值