CodeForcesDiv2第111专场C题
此题题意是给你n个数以及一个k,两两总共有n2 种组合,(p1,q1)<(p2,q2)当p1<p1或者p1=p2,q1<q2两种情况时,如果把所有组合都列出来求出第k个组合,那么肯定超时。所以另觅他径,把n的数排序,考虑相等的情况,比如1 1 1 2 2 5,i = 1,j = 4时,a[i]!=a[j] 此时判断k是否在(i-1)*n和(j-1)*n之间,如果不在,则i=j,否则p1=a[i],p2=a[(k-(i-1)*n)/(j-i)+1],此处3个1有9种组合。
注意(i-1)*n,(j-1)*n的值会超出int范围,有2中做法解决:1.把表达式中的n强制转换成(__int64)类型;2.在输入n值的时候直接申明n的类型为__int64。一个表达式如果左右两边的类型不匹配的时候,类型小的会强制转换成类型大的。
代码如下:
1 #include <iostream>
2 #include <algorithm>
3 #include <string>
4 #include <map>
5 #include <queue>
6 #include <set>
7 #include <fstream>
8 #include <utility>
9 #include <iomanip>
10 #include <stack>
11 #include <list>
12 #include <vector>
13 #include <cstdio>
14 #include <cstdlib>
15 #include <cstring>
16 #include <cmath>
17 #include <ctime>
18 #include <ctype.h>
19 #include <limits.h>
20 using namespace std;
21 int cmp1(const void* a,const void* b){
22 return (*(int*)a)-(*(int*)b);
23 }
24
25 int main()
26 {
27 freopen("F://学习//算法//codeblock//11//in111.txt","r",stdin);
28 //freopen("F://学习//算法//codeblock//11//in.txt","w",stdout);
29 int n;
30 __int64 k;
31 int a[100005];
32 scanf("%d%I64d",&n,&k);
33 //memset(a,0,sizeof(a));
34 int i,j;
35 for(i=1;i<=n;i++){
36 scanf("%d",&a[i]);
37 }
38 qsort(a+1,n,sizeof(a[0]),cmp1);
39 j=1;
40 for(i=1;i<=n;){
41 while(j<=n&&a[i]==a[j]){
42 j++;
43 };
44 //i-1在运算前会转换成n的类型,如果n是int,那么乘积可能溢出,导致随机数,所以应该先把n强制转换成__int64类型
45 //或者在定义n的时候用__int64 类型接收
46 if(k>(__int64)(i-1)*n&&k<=(__int64)(j-1)*n){
47 printf("%d %d\n",a[i],a[(k-(__int64)(i-1)*n-1)/(j-i)+1]);
48 }
49 i=j;
50 }
51 return 0;
52 }
------->froest
扬帆起航,生命正式从这里开始...
爱情终将消失于茫茫的时间洪流之中,沉淀于厚重的黄泥沙丘之下...
爱情终将消失于茫茫的时间洪流之中,沉淀于厚重的黄泥沙丘之下...