Contest2071 - 湖南多校对抗赛(2015.03.28)
Contest2071 - 湖南多校对抗赛(2015.03.28)
本次比赛试题由湖南大学ACM校队原创
http://acm.csu.edu.cn/OnlineJudge/contest.php?cid=2071
Problem A: Rectangle
Time Limit: 1 Sec Memory Limit: 256 MBSubmit: 210 Solved: 48
[Submit][Status][Web Board]
Description
Now ,there are some rectangles. The area of these rectangles is 1* x or 2 * x ,and now you need find a big enough rectangle( 2 * m) so that you can put all rectangles into it(these rectangles can't rotate). please calculate the minimum m satisfy the condition.
Input
There are some tests ,the first line give you the test number.
Each test will give you a number n (1<=n<=100)show the rectangles number .The following n rows , each row will give you tow number a and b. (a = 1 or 2 , 1<=b<=100).
Output
Each test you will output the minimum number m to fill all these rectangles.
Sample Input
2
3
1 2
2 2
2 3
3
1 2
1 2
1 3
Sample Output
7 4
题意:就是说有1*x或者2*x的长方形,你有2*m的总空间,问你m的最小值;
思路:如果是2*x那么x必定是要加的,但是1*x则可以叠加,so把所有的1的宽x加起来,用0-1背包一下就行了;
转载请注明出处:寻找&星空の孩子
#include<stdio.h> const int N = 10005; int main() { int dp[N],ans,t,a[N],b[N],n; scanf("%d",&t); while(t--) { scanf("%d",&n); ans=0; for(int i=0;i<=N;i++) dp[i]=0; int V=0; for(int i=1;i<=n;i++) { scanf("%d%d",&a[i],&b[i]); if(a[i]==1) V+=b[i]; } for(int i=1;i<=n;i++) if(a[i]==2) ans+=b[i]; else { for(int v=V/2;v>=b[i];v--) if(dp[v]<dp[v-b[i]]+b[i]) dp[v]=dp[v-b[i]]+b[i]; } int aa=V-dp[V/2]; if(aa<dp[V/2]) aa=dp[V/2]; ans+=aa; printf("%d\n",ans); } return 0; } /* 2 3 1 2 2 2 2 3 3 1 2 1 2 1 3 */
Problem B: Design road
Time Limit: 2 Sec Memory Limit: 256 MBSubmit: 43 Solved: 18
[Submit][Status][Web Board]
Description
You need to design road from (0, 0) to (x, y) in plane with the lowest cost. Unfortunately, there are N Rivers between (0, 0) and (x, y).It costs c1 Yuan RMB per meter to build road, and it costs c2 Yuan RMB per meter to build a bridge. All rivers are parallel to the Y axis with infinite length.
Input
There are several test cases.
Each test case contains 5 positive integers N,x,y,c1,c2 in the first line.(N ≤ 1000,1 ≤ x,y≤ 100,000,1 ≤ c1,c2 ≤ 1000).
The following N lines, each line contains 2 positive integer xi, wi ( 1 ≤ i ≤ N ,1 ≤ xi ≤x, xi-1+wi-1 < xi , xN+wN ≤ x),indicate the i-th river(left bank) locate xi with wi width.
The input will finish with the end of file.
Output
For each the case, your program will output the least cost P on separate line, the P will be to two decimal places .
Sample Input
1 300 400 100 100
100 50
1 150 90 250 520
30 120
Sample Output
50000.00
80100.00
题意:修路:从(0,0)~(x,y),n个数表示有第二行开始有n行表示有n条河,xi是河的起始位置,wi是河的宽度,有水的地方要修桥,而x,y表示修路的端点,C1表示修路每米的花费,C2表示修桥每米的花费,问你最后花费的最少金额!
思路:先把有河的地方都和到一起,然后它的宽度就知道了,那么就把高度三分,找花费最小的点;看代码就知道了!哈哈
转载请注明出处:
寻找&星空の孩子
#include <stdio.h> #include <string.h> #include <algorithm> #include <math.h> using namespace std; int n; double x,y,c1,c2,sum,ans; double dis(double x1,double y1,double x2,double y2) { return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } void fen_3(double l,double r) { double mid1 = l+(r-l)/3; double mid2 = l+(r-l)*2/3; double s1 = dis(0,0,sum,mid1)*c2+dis(sum,mid1,x,y)*c1; double s2 = dis(0,0,sum,mid2)*c2+dis(sum,mid2,x,y)*c1; if(fabs(s1-s2)<1e-6) { ans = s2; return; } if(s1>s2) fen_3(mid1,r); else fen_3(l,mid2); } int main() { int i,j,k; while(~scanf("%d%lf%lf%lf%lf",&n,&x,&y,&c1,&c2)) { sum = 0; for(i = 0;i<n;i++) { double tx,ty; scanf("%lf%lf",&tx,&ty); sum+=ty; } fen_3(0,y); printf("%.2f\n",ans); } return 0; } /************************************************************** Problem: 1548 User: aking2015 Language: C++ Result: Accepted Time:84 ms Memory:976 kb ****************************************************************/
Problem C: Navigition Problem
Time Limit: 1 Sec Memory Limit: 256 MBSubmit: 56 Solved: 8
[Submit][Status][Web Board]
Description
Navigation is a field of study that focuses on the process of monitoring and controlling the movement of a craft or vehicle from one place to another. The field of navigation includes four general categories: land navigation, marine navigation, aeronautic navigation, and space navigation. (From Wikipedia)
Recently, slowalker encountered a problem in the project development of Navigition APP. In order to provide users with accurate navigation service , the Navigation APP should re-initiate geographic location after the user walked DIST meters. Well, here comes the problem. Given the Road Information which could be abstracted as N segments in two-dimensional space and the distance DIST, your task is to calculate all the postion where the Navigition APP should re-initiate geographic location.
Input
The input file contains multiple test cases.
For each test case,the first line contains an interger N and a real number DIST. The following N+1 lines describe the road information.
You should proceed to the end of file.
Hint:
1 <= N <= 1000
0 < DIST < 10,000
Output
For each the case, your program will output all the positions where the Navigition APP should re-initiate geographic location. Output “No Such Points.” if there is no such postion.
Sample Input
2 0.50
0.00 0.00
1.00 0.00
1.00 1.00
Sample Output
0.50,0.00
1.00,0.00
1.00,0.50
1.00,1.00
HINT
暂没做出。。。。。
Problem D: Simple String
Time Limit: 1 Sec Memory Limit: 256 MBSubmit: 74 Solved: 35
[Submit][Status][Web Board]
Description
Welcome,this is the 2015 3th Multiple Universities Programming Contest ,Changsha ,Hunan Province. In order to let you feel fun, ACgege will give you a simple problem. But is that true? OK, let’s enjoy it.
There are three strings A , B and C. The length of the string A is 2*N, and the length of the string B and C is same to A. You can take N characters from A and take N characters from B. Can you set them to C ?
Input
There are several test cases.
Each test case contains three lines A,B,C. They only contain upper case letter.
0<N<100000
The input will finish with the end of file.
Output
For each the case, if you can get C, please print “YES”. If you cann’t get C, please print “NO”.
Sample Input
AABB
BBCC
AACC
AAAA
BBBB
AAAA
Sample Output
YES
NO
题意:有A,B,C三个集合,取A、B串的各一半,问能不能组成C;
思路:记录每个字符出现的个数,大于一半长度取一半;然后a[i]+b[i]<c[i]的就输出NO;
然后定b[i]判断min_a[i]+=c[i]-b[i];max_a[i]+=a[i];最后判断a[i]的长度len/2是否在min和max之间,在之间就输出YES。不
在之间就输出NO;
转载请注明出处:
寻找&星空の孩子
#include<stdio.h> #include<string.h> const int N = 200005; char A[N],B[N],C[N]; int main() { int a[30],b[30],c[30]; int mint,maxt,flag,len; while(scanf("%s%s%s",A,B,C)>0) { len=strlen(A); for(int i=0;i<=26;i++) a[i]=b[i]=c[i]=0; for(int i=0;i<len;i++) { int j; j=A[i]-'A'; a[j]++; j=B[i]-'A'; b[j]++; j=C[i]-'A'; c[j]++; } flag=0; for(int i=0;i<26;i++) { if(a[i]>len/2) a[i]=len/2; if(b[i]>len/2) b[i]=len/2; if(a[i]+b[i]<c[i]) { flag=1; break; } } if(flag) { printf("NO\n");continue; } mint=maxt=0; for(int i=0;i<26;i++) { if(c[i]>b[i]) mint+=c[i]-b[i]; if(a[i]>=c[i]) maxt+=c[i]; else maxt+=a[i]; } // printf("%d %d\n",mint,maxt); if(len/2>=mint&&len/2<=maxt) printf("YES\n"); else printf("NO\n"); } } /************************************************************** Problem: 1550 User: aking2015 Language: C++ Result: Accepted Time:24 ms Memory:1548 kb ****************************************************************/
Problem E: Longest Increasing Subsequence Again
Time Limit: 2 Sec Memory Limit: 256 MBSubmit: 27 Solved: 13
[Submit][Status][Web Board]
Description
Give you a numeric sequence. If you can demolish arbitrary amount of numbers, what is the length of the longest increasing sequence, which is made up of consecutive numbers? It sounds like Longest Increasing Subsequence at first sight. So, there is another limitation: the numbers you deleted must be consecutive.
Input
There are several test cases.
For each test case, the first line of input contains the length of sequence N(1≤N≤10^4). The second line contains the elements of sequence——N positive integers not larger than 10^4.
Output
For each the case, output one integer per line, denoting the length of the longest increasing sequence of consecutive numbers, which is achievable by demolishing some(may be zero) consecutive numbers.
Sample Input
7
1 7 3 5 9 4 8
6
2 3 100 4 4 5
Sample Output
4
4
HINT
转载请注明出处:
寻找&星空の孩子
#include<stdio.h> #include<algorithm> using namespace std; const int N = 10005; struct qj { int l,r; }kuai[N]; int b[N],tn,n,a[N],k[N],tree[N*4]; void builde(int l,int r,int e) { int m=(l+r)/2; tree[e]=0; if(l==r) return ; builde(l,m,e*2); builde(m+1,r,e*2+1); } void settree(int l,int r,int e,int id,int ans) { int m=(l+r)/2; if(tree[e]<ans) tree[e]=ans; if(l==r) { return ; } if(id<=m) settree(l,m,e*2,id,ans); else settree(m+1,r,e*2+1,id,ans); } int findans(int l,int r,int e,int id) { int m=(l+r)/2,ans=0; if(l==r) return 0; if(id<=m) { ans=findans(l,m,e*2,id); if(ans<tree[e*2+1]) ans=tree[e*2+1]; return ans; } else return findans(m+1,r,e*2+1,id); } int cmp(int aa,int bb) { return aa<bb; } void cut() { tn=1; sort(b+1,b+1+n,cmp); for(int i=2;i<=n;i++) if(b[i]!=b[tn]) b[++tn]=b[i]; } int two(int aa) { int l,r,m; l=1;r=tn; while(l<=r) { m=(l+r)/2; if(b[m]==aa) return m; if(b[m]>aa) r=m-1; else l=m+1; } return m; } int main() { while(scanf("%d",&n)>0) { if(n==0) { printf("0\n");continue; } for(int i=1;i<=n;i++) { scanf("%d",&a[i]); b[i]=a[i]; } cut(); builde(1,tn,1); int m=1; kuai[m].l=kuai[m].r=1; for(int i=2;i<=n;i++) if(a[kuai[m].r]>=a[i]) { m++; kuai[m].l=kuai[m].r=i; } else kuai[m].r++; for(int i=1;i<=m;i++) { for(int j=kuai[i].r;j>=kuai[i].l;j--) k[j]=kuai[i].r-j+1; } int ans=0; for(int i=m;i>0;i--) { int aaa,id; for(int j=kuai[i].r;j>=kuai[i].l;j--) { id=two(a[j]); aaa=j-kuai[i].l+1; aaa+=findans(1,tn,1,id); if(ans<aaa) ans=aaa; } for(int j=kuai[i].r;j>=kuai[i].l;j--) { id=two(a[j]); settree(1,tn,1,id,k[j]); } } printf("%d\n",ans); } } /************************************************************** Problem: 1551 User: aking2015 Language: C++ Result: Accepted Time:192 ms Memory:1320 kb ****************************************************************/
Problem F: Friends
Time Limit: 3 Sec Memory Limit: 256 MBSubmit: 131 Solved: 25
[Submit][Status][Web Board]
Description
On an alien planet, every extraterrestrial is born with a number. If the sum of two numbers is a prime number, then two extraterrestrials can be friends. But every extraterrestrial can only has at most one friend. You are given all number of the extraterrestrials, please determining the maximum number of friend pair.
Input
There are several test cases.
Each test start with positive integers N(1 ≤ N ≤ 100), which means there are N extraterrestrials on the alien planet.
The following N lines, each line contains a positive integer pi ( 2 ≤ pi ≤10^18),indicate the i-th extraterrestrial is born with pi number.
The input will finish with the end of file.
Output
For each the case, your program will output maximum number of friend pair.
Sample Input
3
2
2
3
4
2
5
3
8
Sample Output
1
2
HINT
二分匹配
#include<stdio.h> #include<math.h> #include <algorithm> #include<string.h> #include <time.h> using namespace std; #define ll long long //-----大素数的判断------- ll mult_mod(ll a,ll b,ll n) { ll s=0; while(b) { if(b&1) s=(s+a)%n; a=(a+a)%n; b>>=1; } return s; } ll pow_mod(ll a,ll b,ll n) { ll s=1; while(b) { if(b&1) s=mult_mod(s,a,n); a=mult_mod(a,a,n); b>>=1; } return s; } int Prime(ll n) { ll u=n-1,pre,x; int i,j,k=0; if(n==2||n==3||n==5||n==7||n==11) return 1; if(n==1||(!(n%2))||(!(n%3))||(!(n%5))||(!(n%7))||(!(n%11))) return 0; for(;!(u&1);k++,u>>=1); srand((ll)time(0)); for(i=0;i<5;i++) { x=rand()%(n-2)+2; x=pow_mod(x,u,n); pre=x; for(j=0;j<k;j++) { x=mult_mod(x,x,n); if(x==1&&pre!=1&&pre!=(n-1)) return 0; pre=x; } if(x!=1) return 0; } return 1; } int n,ok[105][105],mark[105],vist[105]; int DFS(int x) { for(int i=1;i<=n;i++) if(ok[x][i]&&vist[i]==0) { vist[i]=1; if(mark[i]==0||DFS(mark[i])) { mark[i]=x; return 1; } } return 0; } int main() { ll a[105]; while(scanf("%d",&n)>0) { for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); } memset(ok,0,sizeof(ok)); for(int i=1;i<n;i++) for(int j=i+1;j<=n;j++) if(Prime(a[i]+a[j])) ok[i][j]=ok[j][i]=1; int ans=0; memset(mark,0,sizeof(mark)); for(int i=1;i<=n;i++) { memset(vist,0,sizeof(vist)); ans+=DFS(i); } printf("%d\n",ans/2); } } /************************************************************** Problem: 1552 User: aking2015 Language: C++ Result: Accepted Time:1640 ms Memory:1012 kb ****************************************************************/
Problem G: Good subsequence
Time Limit: 2 Sec Memory Limit: 256 MBSubmit: 208 Solved: 48
[Submit][Status][Web Board]
Description
Give you a sequence of n numbers, and a number k you should find the max length of Good subsequence. Good subsequence is a continuous subsequence of the given sequence and its maximum value - minimum value<=k. For example n=5, k=2, the sequence ={5, 4, 2, 3, 1}. The answer is 3, the good subsequence are {4, 2, 3} or {2, 3, 1}.
Input
There are several test cases.
Each test case contains two line. the first line are two numbers indicates n and k (1<=n<=10,000, 1<=k<=1,000,000,000). The second line give the sequence of n numbers a[i] (1<=i<=n, 1<=a[i]<=1,000,000,000).
The input will finish with the end of file.
Output
For each the case, output one integer indicates the answer.
Sample Input
5 2
5 4 2 3 1
1 1
1
Sample Output
3
1
HINT
题意:最长连续子序列,要求子序列中最大减去最小的数小于k
思路:。。。。。。
转载请注明出处:
寻找&星空の孩子
#include <stdio.h> #include <stdio.h> #include <algorithm> #include <set> using namespace std; set<int> st; int a[10005]; int main() { int n,k,i,j,ans; while(~scanf("%d%d",&n,&k)) { st.clear(); for(i = 1;i<=n;i++) scanf("%d",&a[i]); ans = 0; for(i = 1,j = 1;i<=n;i++) { st.insert(a[i]); while(*st.rbegin()-*st.begin()>k) { st.erase(st.find(a[j])); j++; } ans = max(ans,i-j+1); } printf("%d\n",ans); } return 0; } /************************************************************** Problem: 1553 User: aking2015 Language: C++ Result: Accepted Time:652 ms Memory:1104 kb ****************************************************************/
Problem H: SG Value
Time Limit: 5 Sec Memory Limit: 256 MBSubmit: 55 Solved: 4
[Submit][Status][Web Board]
Description
The SG value of a set (multiset) is the minimum positive integer that could not be constituted of the number in this set.
You will be start with an empty set, now there are two opertions:
1. insert a number x into the set;
2. query the SG value of current set.
Input
Input contains multiple test cases. Each test case starts with a number N (0 < N <= 1e5) -- the total number of opertions.
The next N lines contain one opertion each.
1 x means insert a namber x into the set;
2 means query the SG value of current set.
Output
For each query output the SG value of current set.
Sample Input
5
2
1 1
2
1 1
2
Sample Output
1 2 3
Problem I: Inversion Sequence
Time Limit: 2 Sec Memory Limit: 256 MBSubmit: 90 Solved: 26
[Submit][Status][Web Board]
Description
For sequence i1, i2, i3, … , iN, we set aj to be the number of members in the sequence which are prior to j and greater to j at the same time. The sequence a1, a2, a3, … , aN is referred to as the inversion sequence of the original sequence (i1, i2, i3, … , iN). For example, sequence 1, 2, 0, 1, 0 is the inversion sequence of sequence 3, 1, 5, 2, 4. Your task is to find a full permutation of 1~N that is an original sequence of a given inversion sequence. If there is no permutation meets the conditions please output “No solution”.
Input
There are several test cases.
Each test case contains 1 positive integers N in the first line.(1 ≤ N ≤ 10000).
Followed in the next line is an inversion sequence a1, a2, a3, … , aN (0 ≤ aj < N)
The input will finish with the end of file.
Output
For each case, please output the permutation of 1~N in one line. If there is no permutation meets the conditions, please output “No solution”.
Sample Input
5
1 2 0 1 0
3
0 0 0
2
1 1
Sample Output
3 1 5 2 4
1 2 3
No solution
HINT
转载请注明出处:
寻找&星空の孩子
#include <stdio.h> #include <string.h> #include <algorithm> #include <math.h> using namespace std; #define ls 2*i #define rs 2*i+1 const int L = 10005; struct node { int l,r,n; } a[L*4]; int n,ans[L],pos; void push_up(int i) { a[i].n = a[ls].n+a[rs].n; } void init(int l,int r,int i) { a[i].l = l; a[i].r = r; if(l==r) { a[i].n = 1; return ; } int mid = (l+r)/2; init(l,mid,ls); init(mid+1,r,rs); push_up(i); } void query(int i,int x) { if(a[i].l == a[i].r) { pos = a[i].l; a[i].n = 0; return ; } if(x<=a[ls].n) query(ls,x); else query(rs,x-a[ls].n); push_up(i); } int main() { int i,j,k,x; while(~scanf("%d",&n)) { memset(ans,0,sizeof(ans)); init(1,n,1); int flag = 0; for(i = 1; i<=n; i++) { scanf("%d",&x); if(flag) continue; if(a[1].n<x+1) { flag = 1; continue; } else { query(1,x+1); ans[pos] = i; } } if(flag) printf("No solution\n"); else { printf("%d",ans[1]); for(i = 2; i<=n; i++) printf(" %d",ans[i]); printf("\n"); } } return 0; } /************************************************************** Problem: 1555 User: aking2015 Language: C++ Result: Accepted Time:192 ms Memory:1472 kb ****************************************************************/
Problem J: Jerry's trouble
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 96 Solved: 46
[Submit][Status][Web Board]
Description
Jerry is caught by Tom. He was penned up in one room with a door, which only can be opened by its code. The code is the answer of the sum of the sequence of number written on the door. The type of the sequence of number is
But Jerry’s mathematics is poor, help him to escape from the room.
Input
There are some cases (about 500). For each case, there are two integer numbers n, m describe as above ( 1 <= n < 1 000 000, 1 <= m < 1000).
Output
For each case, you program will output the answer of the sum of the sequence of number (mod 1e9+7).
Sample Input
4 1
5 1
4 2
5 2
4 3
Sample Output
10
15
30
55
100
HINT
转载请注明出处:
寻找&星空の孩子
#include<stdio.h> #define LL long long const LL mod=1e9+7; inline LL two(LL &a,LL m) { if(m==0) return 1; LL ans=two(a,m/2); ans=(ans*ans)%mod; if(m&1) ans=(ans*a)%mod; return ans; } int main() { LL n,m,i; while(scanf("%lld%lld",&n,&m)>0) { LL ans=0; for(i=1;i<=n;i++) ans=(ans+two(i,m))%mod; printf("%lld\n",ans); } } /************************************************************** Problem: 1556 User: aking2015 Language: C++ Result: Accepted Time:3012 ms Memory:964 kb ****************************************************************/