浙南联合训练赛20171202
Posted BobHuang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浙南联合训练赛20171202相关的知识,希望对你有一定的参考价值。
A - Tiling_easy version
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
- 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
Output
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
Input
Output
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!
“升级”?“双扣”?“红五”?还是“斗地主”?
当然都不是!那多俗啊~
作为计算机学院的学生,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
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
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
Output
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的主要内容,如果未能解决你的问题,请参考以下文章