2016 ACM/ICPC Asia Regional Qingdao Online(青岛网络赛)
部分题解(A,B,E,F)
A
I Count Two ThreeTime Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1676 Accepted Submission(s): 757
Problem Description
I will show you the most popular board game in the Shanghai Ingress Resistance Team.
It all started several months ago. We found out the home address of the enlightened agent Icount2three and decided to draw him out. Millions of missiles were detonated, but some of them failed. After the event, we analysed the laws of failed attacks. It's interesting that the At recent dinner parties, we call the integers with the form A related board game with a given positive integer
Input
The first line of input contains an integer
Output
For each test case, output one line with only one integer corresponding to the shortest "I Count Two Three Number" no smaller than
Sample Input
Sample Output
|
先打表,后二分查找;
二分查找 可以用两种方法 一种是自己写的, 另一种是用STL 中自带的 二分查找., 但是自带的是返回double 直接用可能会存在误差 所以;
STL中自带二分查找
返回的是double 型可能会存在精度误差
STL中的每个算法都非常精妙,接下来的几天我想集中学习一下STL中的算法。
ForwardIter lower_bound(ForwardIter first, ForwardIter last,const _Tp&val)算法返回一个非递减序列[first, last)中的第一个大于等于值val的位置。
ForwardIterupper_bound(ForwardIter first, ForwardIter last,const _Tp& val)算法返回一个非递减序列[first, last)中第一个大于val的位置。
#include <iostream> #include <queue> #include <algorithm> #include <cmath> #include <stdio.h> #include <cstring> #include <stdlib.h> using namespace std; const int INF=1000000; typedef long long ll; ll a[100010]; ll pow(ll x,ll n) { ll res=1; while(n>0) { if(n & 1) res=(res*x); x=(x*x); n >>= 1; } return res; } int s=0; void init() { ll t; for(int i=0;i<=31;i++) for(int j=0;j<=20;j++) for(int k=0;k<=14;k++) for(int x=0;x<=12;x++){ t=pow(2,i)*pow(3,j); //cout<<t<<endl; if(t>1e9) break; t*=pow(5,k); if(t>1e9) break; t*=pow(7,x); if(t>1e9) break; a[s++]=t; } sort(a,a+s); } ll finds(int x) { int le=0,ri=s-1; while(le<=ri) { int mid=(le+ri)/2; if(x>a[mid]) le=mid+1; else ri=mid-1; } printf("%lld\n",a[le]); } int main() { init(); int t; //freopen("input.txt","r",stdin); cin>>t; ll num; while(t--) { scanf("%lld",&num); ll ans=lower_bound(a,a+s,num)-a; printf("%lld\n",a[ans]); //finds(num); } return 0; }
B-
Cure
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2523 Accepted Submission(s): 689
Problem Description
Given an integer n ,
we only want to know the sum of 1/k2 where k from 1 to n .
Input
There are multiple cases.
For each test case, there is a single line, containing a single positive integern .
The input file is at most 1M.
For each test case, there is a single line, containing a single positive integer
The input file is at most 1M.
Output
The required sum, rounded to the fifth digits after the decimal point.
Sample Input
1 2 4 8 15
Sample Output
1.00000 1.25000 1.42361 1.52742 1.58044
打表;
#include <iostream> #include <queue> #include <algorithm> #include <cmath> #include <stdio.h> #include <cstring> #include <stdlib.h> using namespace std; typedef long long ll; double k; char str[2020000]; double a[2020000]; int main() { ll n; for(ll i=1;i<1000000;i++) a[i]=a[i-1]+1.0/(i*i); while(~scanf("%s",&str)) { if(strlen(str)>6) n=999999; else { ll num=0; num=atof(str); n=num; } if(n>1000000||n<0) n=999999; printf("%.5lf\n",a[n]); } return 0; }
F -
The Best Path
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1435 Accepted Submission(s): 608
Problem Description
Alice is planning her travel route in a beautiful valley. In this valley, there are N lakes,
and M rivers
linking these lakes. Alice wants to start her trip from one lake, and enjoys the landscape by boat. That means she need to set up a path which go through every river exactly once. In addition, Alice has a specific number (a1,a2,...,an )
for each lake. If the path she finds is P0→P1→...→Pt ,
the lucky number of this trip would be aP0XORaP1XOR...XORaPt .
She want to make this number as large as possible. Can you help her?
Input
The first line of input contains an integer t ,
the number of test cases. t test
cases follow.
For each test case, in the first line there are two positive integersN (N≤100000) and M (M≤500000) ,
as described above. The i -th
line of the next N lines
contains an integer ai(∀i,0≤ai≤10000) representing
the number of the i -th
lake.
Thei -th
line of the next M lines
contains two integers ui and vi representing
the i -th
river between the ui -th
lake and vi -th
lake. It is possible that ui=vi .
For each test case, in the first line there are two positive integers
The
Output
For each test cases, output the largest lucky number. If it dose not have any path, output "Impossible".
Sample Input
2 3 2 3 4 5 1 2 2 3 4 3 1 2 3 4 1 2 2 3 2 4
Sample Output
2 Impossible
欧拉回路与通路 + 并查集
注意分析 结果为 回路时 和与通路时 , 亦或值 要取最大;
#include <iostream> #include <queue> #include <algorithm> #include <cmath> #include <stdio.h> #include <cstring> #include <stdlib.h> using namespace std; int a[101000]; int pre[101000]; int b[101000]; int find(int x) { return pre[x]== x? x: (pre[x]=find(pre[x])); } void join(int x,int y) { int fx=find(x),fy=find(y); if(fx!=fy) pre[fx]=fy; } int main() { int T; int n,m; int x,y; //freopen("input.txt","r",stdin); cin>>T; while(T--) { memset(a,0,sizeof(a)); scanf("%d %d",&n,&m); int sum=0; for(int i=1;i<=n;i++){ scanf("%d",&b[i]); pre[i]=i; } for(int i=1;i<=m;i++) { scanf("%d %d",&x,&y); join(x,y); a[x]++; a[y]++; } int flag=1; int cont=0; int co=0; for(int i=1;i<=n;i++) { if(find(i)==i) co++; } if(co>1) flag=0; else { for(int i=1;i<=n;i++) if(a[i]%2!=0) cont++; if(cont!=0&&cont!=2) flag=0; //分别讨论 度为0 或为1 if(cont==0)// 为0 是回路, 枚举起点,找亦或最大值 { for(int i=1;i<=n;i++) sum=max(sum^b[i],sum); } if(cont==2)// 为2 通路, { for(int i=1;i<=n;i++) { if(((a[i]+1)/2)&1)//奇数 { sum^=b[i]; } } } } if(flag) printf("%d\n",sum); else printf("Impossible\n"); } return 0; }
岂曰无衣?与子同袍。王于兴师,修我戈矛。与子同仇!
岂曰无衣?与子同泽。王于兴师,修我矛戟。与子偕作!
岂曰无衣?与子同裳。王于兴师,修我甲兵。与子偕行!