浙南联合训练赛20171202

Posted BobHuang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浙南联合训练赛20171202相关的知识,希望对你有一定的参考价值。

A - Tiling_easy version

有一个大小是 2 x n 的网格,现在需要用2种规格的骨牌铺满,骨牌规格分别是 2 x 1 和 2 x 2,请计算一共有多少种铺设的方法。 

Input输入的第一行包含一个正整数T(T<=20),表示一共有 T组数据,接着是T行数据,每行包含一个正整数N(N<=30),表示网格的大小是2行N列。 
Output输出一共有多少种铺设的方法,每组数据的输出占一行。 
Sample Input

3
2
8
12

Sample Output

3
171
2731

这个和那个骨牌覆盖相比简单多了,那个要状压dp,这个本来看起来毫无头绪,因为我列出来的前几个数也没找到规律

后来看时我就去模拟这个过程,比如2的时候有三种,3的话可以在1的基础上放,把这两个当作一块有两种方法,在2的基础上只能放上1×2,相当于没有增加,

打出来试了样列对了就交了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dp[35];
int main()
{
    dp[1]=1,dp[2]=3;
    for(int j=3;j<31;j++)
        {
            dp[j]=dp[j-2]*2+dp[j-1];
        }
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        cin>>n;
        cout<<dp[n]<<"\n";
    }
    return 0;
}

B - Basically Speaking

The Really Neato Calculator Company, Inc. has recently hired your team to help design their Super Neato Model I calculator. As a computer scientist you suggested to the company that it would be neato if this new calculator could convert among number bases. The company thought this was a stupendous idea and has asked your team to come up with the prototype program for doing base conversion. The project manager of the Super Neato Model I calculator has informed you that the calculator will have the following neato features: 

  • It will have a 7-digital display. 
  • Its buttons will include the capital letters A through F in addition to the digits 0 through 9. 
  • It will support bases 2 through 16. 

Input

The input for your prototype program will consist of one base conversion per line. There will be three numbers per line. The first number will be the number in the base you are converting from. The second number is the base you are converting from. The third number is the base you are converting to. There will be one or more blanks surrounding (on either side of) the numbers. There are several lines of input and your program should continue to read until the end of file is reached.

Output

The output will only be the converted number as it would appear on the display of the calculator. The number should be right justified in the 7-digit display. If the number is to large to appear on the display, then print ``ERROR‘‘ (without the quotes) right justified in the display.

Sample Input

1111000  2 10
1111000  2 16
2102101  3 10
2102101  3 15
  12312  4  2
     1A 15  2
1234567 10 16
   ABCD 16 15

Sample Output

    120
     78
   1765
    7CA
  ERROR
  11001
 12D687
   D071

B是个直接用stl艹过去的,因为2-16进制,都以16进制读入然后进行进制转换就可以了,这样可以解决对空格的处理

#include<stdio.h>
#include<string>
#include<algorithm>
#include<iostream>
using namespace std;
string f;
void la(int n, int b)
{
    static char c[16]= {0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F};
    f="";
    if(!n)f="0";
    while(n)
    {
        f+=c[n%b];
        n=n/b;
    }
    if(f.length()>7)
        f="RORRE";
    for(int i=f.length(); i<7; i++)
        f+= ;
    reverse(f.begin(),f.end());
    cout<<f<<"\n";
}

int main()
{
    int n,a,b;
    while(~scanf("%X%d%d",&n,&a,&b))
    {
        string s;
        while(n)
        {
            s+=n%16;
            n/=16;
        }
        int sum=0;
        for(int i=s.size()-1;i>=0;i--)
            sum=sum*a+s[i];
        la(sum,b);
    }
    return 0;
}

看了聚聚用的函数,把自己代码优化下

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
    long n;
    char a[32],b[32];
    int p,q;
    while(~scanf("%s%d%d",a,&p,&q))
    {
        memset(b,0,sizeof b);
        n=strtol(a,0,p);
        int t=0;
        while(n)
        {
            int m=n%q;
            b[t++]=m<10?0+m:A+m-10;
            n/=q;
        }
        if(b[7])puts("  ERROR");
        else
        {
            for(int i=6;i>=0;i--)
                putchar(b[i]?b[i]: );
            putchar(10);
        }
    }
    return 0;
}

 

C - Lifting the Stone

There are many secret openings in the floor which are covered by a big heavy stone. When the stone is lifted up, a special mechanism detects this and activates poisoned arrows that are shot near the opening. The only possibility is to lift the stone very slowly and carefully. The ACM team must connect a rope to the stone and then lift it using a pulley. Moreover, the stone must be lifted all at once; no side can rise before another. So it is very important to find the centre of gravity and connect the rope exactly to that point. The stone has a polygonal shape and its height is the same throughout the whole polygonal area. Your task is to find the centre of gravity for the given polygon.

Input

The input consists of T test cases. The number of them (T) is given on the first line of the input file. Each test case begins with a line containing a single integer N (3 <= N <= 1000000) indicating the number of points that form the polygon. This is followed by N lines, each containing two integers Xi and Yi (|Xi|, |Yi| <= 20000). These numbers are the coordinates of the i-th point. When we connect the points in the given order, we get a polygon. You may assume that the edges never touch each other (except the neighboring ones) and that they never cross. The area of the polygon is never zero, i.e. it cannot collapse into a single line.

Output

Print exactly one line for each test case. The line should contain exactly two numbers separated by one space. These numbers are the coordinates of the centre of gravity. Round the coordinates to the nearest number with exactly two digits after the decimal point (0.005 rounds up to 0.01). Note that the centre of gravity may be outside the polygon, if its shape is not convex. If there is such a case in the input data, print the centre anyway. 

Sample Input

2
4
5 0
0 5
-5 0
0 -5
4
1 1
11 1
11 11
1 11

Sample Output

0.00 0.00
6.00 6.00

求一个多边形的重心,这个真不会啊,拿三角形来回试,好像找到了规律,但是忽略了钝角三角形的重心实在它外面的,这个有向面积是可以表示的,我竟然取了fabs,GG

#include<stdio.h>
#include<math.h>
double area(double x1,double y1,double x2,double y2,double x3,double y3)
{
    return (x1*y2+x2*y3+x3*y1-x1*y3-x2*y1-x3*y2);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        double x1,x2,x3,y1,y2,y3;
        scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
        double s=0,sx=0,sy=0;
        for(int i=2; i<n; i++)
        {
            scanf("%lf%lf",&x3,&y3);
            double ss=area(x1,y1,x2,y2,x3,y3);
            s+=ss;
            sx+=(x1+x2+x3)*ss;
            sy+=(y1+y2+y3)*ss;
            x2=x3,y2=y3;
        }
        s*=3;
        printf("%.2f %.2f\n",sx/s,sy/s);
    }
    return 0;
}

换个类型加速下

#include<stdio.h>
#include<math.h>
double area(double x1,double y1,double x2,double y2,double x3,double y3)
{
    return (x1*y2+x2*y3+x3*y1-x1*y3-x2*y1-x3*y2);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        double x1,x2,x3,y1,y2,y3;
        scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
        double s=0,sx=0,sy=0;
        for(int i=2; i<n; i++)
        {
            scanf("%lf%lf",&x3,&y3);
            double ss=area(x1,y1,x2,y2,x3,y3);
            s+=ss;
            sx+=(x1+x2+x3)*ss;
            sy+=(y1+y2+y3)*ss;
            x2=x3,y2=y3;
        }
        s*=3;
        printf("%.2f %.2f\n",sx/s,sy/s);
    }
    return 0;
}

D - Good Luck in CET-4 Everybody!

 

大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的ACM都没工夫练习了,反正我知道的Kiki和Cici都是如此。当然,作为在考场浸润了十几载的当代大学生,Kiki和Cici更懂得考前的放松,所谓“张弛有道”就是这个意思。这不,Kiki和Cici在每天晚上休息之前都要玩一会儿扑克牌以放松神经。 
“升级”?“双扣”?“红五”?还是“斗地主”? 
当然都不是!那多俗啊~ 
作为计算机学院的学生,Kiki和Cici打牌的时候可没忘记专业,她们打牌的规则是这样的: 
1、  总共n张牌; 
2、  双方轮流抓牌; 
3、  每人每次抓牌的个数只能是2的幂次(即:1,2,4,8,16…) 
4、  抓完牌,胜负结果也出来了:最后抓完牌的人为胜者; 
假设Kiki和Cici都是足够聪明(其实不用假设,哪有不聪明的学生~),并且每次都是Kiki先抓牌,请问谁能赢呢? 
当然,打牌无论谁赢都问题不大,重要的是马上到来的CET-4能有好的状态。 

Good luck in CET-4 everybody! 

Input输入数据包含多个测试用例,每个测试用例占一行,包含一个整数n(1<=n<=1000)。Output如果Kiki能赢的话,请输出“Kiki”,否则请输出“Cici”,每个实例的输出占一行。 
Sample Input

1
3

Sample Output

Kiki
Cici

是个博弈找不到规律,自己手动模拟了几个值,猜了很多规律都错了,试了几个数就3可以,然后依旧wa,然后发现能被3整除就行了

就是把它分成这样的1和2的两块,Kiki无法取胜

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    while(~scanf("%d",&n))
        printf("%s",(n%3!=0)?"Kiki\n":"Cici\n");
    return 0;
}

E - Baskets of Gold Coins

 

You are given N baskets of gold coins. The baskets are numbered from 1 to N. In all except one of the baskets, each gold coin weighs w grams. In the one exceptional basket, each gold coin weighs w-d grams. A wizard appears on the scene and takes 1 coin from Basket 1, 2 coins from Basket 2, and so on, up to and including N-1 coins from Basket N-1. He does not take any coins from Basket N. He weighs the selected coins and concludes which of the N baskets contains the lighter coins. Your mission is to emulate the wizard‘s computation. 

InputThe input file will consist of one or more lines; each line will contain data for one instance of the problem. More specifically, each line will contain four positive integers, separated by one blank space. The first three integers are, respectively, the numbers N, w, and d, as described above. The fourth integer is the result of weighing the selected coins. 

N will be at least 2 and not more than 8000. The value of w will be at most 30. The value of d will be less than w. 


OutputFor each instance of the problem, your program will produce one line of output, consisting of one positive integer: the number of the basket that contains lighter coins than the other baskets. 

Sample Input

10 25 8 1109
10 25 8 1045
8000 30 12 959879400

Sample Output

2
10
50

求出前n-1个篮子的和s,我用了当前编号去hash,与题目给的m比较,恰好为n即第n个篮子为w-d的,否则就是差/d;

所以说等差数列求和也是可以的

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    int n,w,d,m;
    while(~scanf("%d%d%d%d",&n,&w,&d,&m))
    {
        ll s=0;
        for(int i=0;i<n;i++)
            s+=i*w;
        ll ans=s-m;
        if(ans==0)cout<<n<<endl;
        else cout<<ans/d<<endl;
    }
    return 0;
}

 

F - Strategic Game

 

Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is very sad. Now he has the following problem. He must defend a medieval city, the roads of which form a tree. He has to put the minimum number of soldiers on the nodes so that they can observe all the edges. Can you help him?

Your program should find the minimum number of soldiers that Bob has to put for a given tree.

The input file contains several data sets in text format. Each data set represents a tree with the following description:

the number of nodes
the description of each node in the following format
node_identifier:(number_of_roads) node_identifier1 node_identifier2 ... node_identifier
or
node_identifier:(0)

The node identifiers are integer numbers between 0 and n-1, for n nodes (0 < n <= 1500). Every edge appears only once in the input data.

For example for the tree:

技术分享图片

the solution is one soldier ( at the node 1).

The output should be printed on the standard output. For each given input data set, print one integer number in a single line that gives the result (the minimum number of soldiers). An example is given in the following table:


Input

4
0:(1) 1
1:(2) 2 3
2:(0)
3:(0)
5
3:(3) 1 4 2
1:(1) 0
2:(0)
0:(0)
4:(0)


Output

1
2


二分图的最小点覆盖裸题,但是还是不太熟悉

#include<bits/stdc++.h>
using namespace std;
const int N=1505;
vector<int>G[N];
int vis[N],mask[N],n;
bool dfs(int u)
{
    for (int i=0; i<G[u].size(); i++)
    {
        int v=G[u][i];
        if(vis[v]==0)
        {
            vis[v]=1;
            if (mask[v]==-1||dfs(mask[v]))
            {
                mask[v]=u;
                return 1;
            }
        }
    }
    return 0;
}
int main()
{
    while(~scanf("%d",&n))
    {
        memset(mask,-1,sizeof(mask));
        for(int i=0; i<n; i++)
            G[i].clear();
        for(int i=0; i<n; i++)
        {
            int u,v,m;
            scanf("%d:(%d)",&u,&m);
            for(int j=0; j<m; j++)
            {
                scanf("%d",&v);
                G[u].push_back(v);
                G[v].push_back(u);
            }
        }
        int ans=0;
        for (int i=0; i<n; i++)
        {
            memset(vis,0,sizeof(vis));
                ans+=dfs(i);
        }
        if(n==1)printf("1\n");
        else printf("%d\n",ans/2);
    }
    return 0;
}

J - Inversion

 

The inversion number of an integer sequence a1, a2, . . . , an is the number of pairs (ai, aj) that satisfy i < j and ai > aj . Given n and the inversion number m, your task is to find the smallest permutation of the set { 1, 2, . . . , n }, whose inversion number is exactly m. 
A permutation a1, a2, . . . , an is smaller than b1, b2, . . . , bn if and only if there exists an integer k such that aj = bj for 1 <= j < k but ak < bk.

Input

The input consists of several test cases. Each line of the input contains two integers n and m. Both of the integers at the last line of the input is ?1, which should not be processed. You may assume that 1 <= n <= 50000 and 0 <= m <= n(n ? 1)/2.

Output

For each test case, print a line containing the smallest permutation as described above, separates the numbers by single spaces.

Sample Input

5 9
7 3
-1 -1

Sample Output

4 5 3 2 1
1 2 3 4 7 6 5

构造题,本来想着树状数组,归并排序的题。但是n个数m个逆序对排列很多啊,所以只能想构造了,

要求字典序最小,所以先构造的是1-x,找到x的最小值

最后一段序列为n~i,所以即求中间的这个数,n-i个数构成(n-i)*(n-i-1)/2个逆序对,求这个值需要构成的逆序对数,就是那个玩意,+i是因为当前最小值为i

#include<stdio.h>
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m))
    {
        if(m==-1&&n==-1)break;
        int s=0,i=n;
        for(;i>1;i--)
        {
            s+=n-i;
            if(s>=m)break;
        }
        for(int j=1;j<i;j++)
        printf("%d ",j);
        int f=m+i-(n-i)*(n-i-1)/2;
        printf("%d",f);
        for(int j=n;j>=i;j--)
            if(j!=f)
            printf(" %d",j);
        putchar(10);
    }
    return 0;
}

 

K - Big Number

 

In many applications very large integers numbers are required. Some of these applications are using keys for secure transmission of data, encryption, etc. In this problem you are given a number, you have to determine the number of digits in the factorial of the number.

 

Input

Input consists of several lines of integer numbers. The first line contains an integer n, which is the number of cases to be tested, followed by n lines, one integer 1 <= n <= 10^7 on each line.

 


<b< dd="">

Output

The output contains the number of digits in the factorial of the integers appearing in the input.

 


<b< dd="">

Sample Input

2
10
20

 


<b< dd="">

Sample Output

7
19


 

一个数的阶乘的位数,斯特林公式

#include<bits/stdc++.h>
using namespace std;
const double pi=acos(-1.),e=exp(1);
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int x;
        cin>>x;
        if(x==1)
            printf("1\n");
        else
        {
            long long gg=(log10(2*pi)+log10(x))/2+x*(log10(x)-log10(e));
            printf("%lld\n", gg+1);
        }
    }
    return 0;
}

 






































































以上是关于浙南联合训练赛20171202的主要内容,如果未能解决你的问题,请参考以下文章

浙南联合训练赛20180214

浙南联合训练赛 B-Laptops

浙南联合训练赛 D - Broken Clock

浙南联合训练赛 H - The number of positions

迎接2019多校联合新生训练赛(2018/12/31)

2018-2019赛季多校联合新生训练赛第三场(2018/12/8)补题题解