模和最大(贪心)

2019-04-13 14:38发布

模和最大 Description   有个数组a, 对于每个a[i],你要找到一个a[j] (i != j) ,使得 (a[i] + a[j]) % p最大。 Input   输入第一行两个整数n,p。 第二行n个整数a[i]。 2 <= n <= 1e6. 2 <= p <= 1e9. a[i] < p. Output   一行输出n个整数,空格分开,最后一个数后面不要有空格。 Sample Input 1  5 7 2 3 3 4 5 Sample Output 1 6 6 6 6 2 具体看注释。 AC代码: #include using namespace std; const int maxn = 1e6 + 10; int a[maxn]; int b[maxn]; int main() { int n, p; scanf("%d%d", &n, &p); for(int i = 1; i <= n; i ++){ scanf("%d", &a[i]); b[i] = a[i]; } sort(b + 1, b + n + 1); int index; for(int i = 1;i <= n;i ++){ index = lower_bound(b + 1,b + n + 1,p - a[i]) - b - 1; ///每一次寻找最后一个小于a[i] 的数 if(index > 0 && b[index] != a[i]) printf("%d",a[i] + b[index]); ///如果找到,且 b[index] != a[i] 即 排除了 i == j 的情况,直接输出 else if(index > 0 && b[index] == a[i]){ ///找到了,但是有可能找的就是自己 if(index > 1) printf("%d",b[index-1] + a[i]); ///如果index > 1, index 左的数 + a[i] 一定最大 else printf("%d",(b[n-(a[i] == b[n])] + a[i]) % p); /// == 1, index 位置左边没有数,直接加上最后的一个数,↓ } ///同时要判断 a[i] 是不是与 最后一个数相等 如果相等,就需要再次向前移一位,排除 选到 a[i] 自己的情况 else printf("%d",(b[n-(a[i] == b[n])] + a[i]) % p); ///找不到一个小于a[i] 的数, 与上同理 if(i != n) printf(" "); } printf(" "); return 0; }   下面的记录给自己看的  QAQ....   看看自己多蠢... 同理, lower_bound()  也可以直接寻找 是否存在 p - a[i] - 1, 如果存在,则可以直接输出 p - 1, 不过情况更为复杂一点。 设 lower_bound()  返回的值是  index,   当然   首先需要判断  b[index]  是否 等于  p - a[i] - 1, 还需要判断  a[i] 是否 等于 p - a[i] - 1 ,要排除 选到自身的情况。      还需要判断 是否能寻找到   >= p - a[i] - 1 的数, 寻找不到就直接输出(a[i] + b[n - (a[i] == b[n])]) % p ,  其中   -(a[i] == b[n]) 与上述理由相同。    最麻烦的就是  寻找到的是  >p - a[i] - 1 的位置,  需要判断 index 是否在首位 是否在 第二位。 举个栗子。 5 10
1 2 3 7 9 以及 5 10 9 8 7 3 9   AC代码: ///下标从 0 开始!! #include using namespace std; const int maxn = 1e6 + 10; int a[maxn]; int b[maxn]; int main() { int n, p; scanf("%d%d", &n, &p); for(int i = 0; i < n; i ++) scanf("%d", &a[i]), b[i] = a[i]; sort(b, b + n); int index; for(int i = 0; i < n; i ++) { index = lower_bound(b, b + n, p - a[i] - 1) - b; if(index == n) printf("%d", (a[i] + b[n - 1 - (a[i] == b[n-1])]) % p); else if(b[index] == p - a[i] - 1) { if(a[i] != p - a[i] - 1) printf("%d", p - 1); else { if(b[index + 1] == a[i]) printf("%d", p - 1); ///出现 相等的情况, 也有可能 后面还有一位 a[] == p - a[i] - 1, 当然 此个 a 是最优 else if(index != 0) printf("%d", b[index - 1] + a[i]); else printf("%d", (a[i] + b[n - 1-(a[i] == b[n-1])]) % p); } } else { if(index == 0){ printf("%d",(a[i] + b[n-1-(a[i] == b[n-1])]) % p); } else { if(index == 1){ if(b[index-1] == a[i]) printf("%d",(a[i] + b[n-1]) % p); else printf("%d",(a[i] + b[index-1]) % p); } else printf("%d",max((a[i] + b[n-1-(a[i] == b[n-1])]) % p,(a[i] + b[index-1-(a[i] == b[index - 1])]) % p)); } } if(i != n - 1)printf(" "); } printf(" "); return 0; }