水题啊,但是却是我最大的痛,由于没弄清题意,结果重测时没想到竟然WA了,最后导致我才2题悲剧地掉rating了不想解释了...
题目大意:给一个序列,要让这个序列的最小值x,最大值y,满足x*2 >= y. 问最少需要删除几个数
我的思路:
这题和上一场的C题的方法是一样的。
先把这个序列A排序,然后枚举“区间”的最右点right, 找这个区间满足arr【left】*2 <= A【right】的最左点。可以看出是满足单调性的,所以用二分可以找到。也可以通过维护一个指针p,使得A【p】*2 <= A【right】。
然后这个区间肯定是满足条件的,所以把除了这个区间之外的数全部删掉。最后看删得最少的区间那个就是答案。
代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #define REP(i,n) for(int i=0; i<(n); ++i) using namespace std; typedef long long int64; const int MAXN = 1000005; int n, m; int arr[MAXN]; int main(){ #ifndef LOCAL freopen("input.txt","r", stdin); freopen("output.txt","w",stdout); #endif while(~scanf("%d", &n)){ REP(i, n)scanf("%d", &arr[i]); sort(arr, arr+n); if(arr[0] * 2 >= arr[n-1]){ puts("0"); } else{ int p=0, ans=MAXN+10; for(int i=1; i<n; ++i){ while(arr[p]*2 < arr[i]) ++p; int now = p + (n - 1)-i; if(now < ans) ans=now; } printf("%d\n", ans); } } return 0; }
第一眼看过去,感觉挺吓人的。再仔细分析一下,其实是很水的。
从r1到r2, 它不一定是直接直直的移到那一行的,它可能是移动到i行,然后再移动到r2行。所以我们可以枚举“中转站”i, 然后算出r1-> i -> r2,共走了s1行。 走到r2行之后,就要走到c2列去了。这时,走了那么多行由于不同行的长度不一样,所以原先在r1列,现在可能已经不在r1了。所以要求出当前在第几列。 通过观察,其实可以发现就是r1 -> i -> r2这段路程中,长度最小的那行len, 然后min(r1, len)就是当前所在列了。
代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #define REP(i,n) for(int i=0; i<(n); ++i) #define FOR(i,s,t) for(int i=(s); i<(t); ++i) using namespace std; typedef long long int64; const int MAXN = 1000005; int n, m; int arr[MAXN]; int getMin(int r1, int r2, int c){ int minx = c; if(r1 < r2){ for(int i=r1+1; i<=r2; ++i){ if(arr[i]+1 < minx) minx=arr[i]+1; } } else{ for(int i=r1-1; i>=r2; --i){ if(arr[i]+1 < minx) minx=arr[i]+1; } } return minx; } int main(){ #ifndef LOCAL freopen("input.txt","r", stdin); freopen("output.txt","w",stdout); #endif int r1, c1, r2, c2; while(~scanf("%d", &n)){ FOR(i,1,n+1) scanf("%d", &arr[i]); scanf("%d%d%d%d",&r1,&c1,&r2,&c2); int ans=MAXN+100; for(int i=1; i<=n; ++i){ int min1 = getMin(r1, i, c1); int min2 = getMin(i, r2, min1); int tmp = abs(r1-i) + abs(i-r2) + abs(c2-min2); if(tmp < ans) ans=tmp; } printf("%d\n", ans); } return 0; }
原创http://blog.csdn.net/shuangde800 (转载请标明)