昨天打的bc,虽然只做出一道题,但还是贴出来吧。。。
这是第一个,一看小数据,二话不说暴力秒之。
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cmath>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <sstream>
#include <ctype.h>
#include <cctype>
#include <string.h>
using namespace std;
const int N = 500;
const int INF = 10000000;
int main()
{
// freopen("in.txt", "r", stdin);
int t, n, a[N];
scanf("%d", &t);
while(t --)
{
scanf("%d", &n);
memset(a, 0, sizeof(a));
for(int i = 0; i < n; i ++)
{
scanf("%d", &a[i]);
}
double num = 0;
for(int i = 0; i < n; i ++)
{
for(int j = 0; j < n; j ++)
{
if(i == j) continue;
if(a[j] < a[i]) num ++;
}
}
// printf("%lf\n", num);
printf("%lf\n", num / ((n * (n - 1))));
}
return 0;
}
刚开始一看这题,我本来想先把n平分,因为是连续的,所以前后分别遍历加一。后来发现不对,第四组数据隔了两个,所以把最后一个数拿出来单独讨论,最后再讨论奇偶。这就是我和队友昨天想出的方法,还用了别的但是失败了,这个方法很遗憾最后也没敲出来。今天敲完提交,结果是WA,事实证明从算法上看就是错的。
这个是我没做出来看的房间里别的神牛的代码,真是太精辟了,我来说明下吧。
既然是连续的,刚开始就建立1 2 3 4 5...(共k个)的数学模型,求和之后从n减去,然后把剩下的平分为k份,从后往前依次加到这个数学模型上。余数另外存起来,拆成多个1,然后从后往前加上去,至于为毛不能从前往后,那是因为前面的数会和后面的数重复。真的只是数学模型的构建,受益匪浅哪。。。
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cmath>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <sstream>
#include <ctype.h>
#include <cctype>
#include <string.h>
using namespace std;
const int N = 500;
const int MOD = 1000000007;
int main()
{
// freopen("in.txt", "r", stdin);
int t;
__int64 ans, n, k, buf;
scanf("%d", &t);
while(t --)
{
scanf("%I64d%I64d", &n, &k);
buf = k * (1 + k) / 2;
if(n < buf) ans = -1;
else
{
int p, q;
ans = 1;
p = n - buf;
q = p % k;
p = p / k;
int j = q, ad;
for(int i = p + k; i >= p + 1; i --)
{
if(j > 0) ad = 1;
else ad = 0;
ans *= (i + ad);
ans = ans % MOD;
j --;
}
}
printf("%I64d\n", ans);
}
return 0;
}
下面是我的方法,事实证明最后一个数拿出来单独讨论,其就有可能与前面的数重复。如果用的个set之类的容器判重,那该数怎么办,要想变该数则就要动前面的数,然后就over了= =。所以这题我是真不会,受教了。
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cmath>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <sstream>
#include <ctype.h>
#include <cctype>
#include <string.h>
using namespace std;
const int N = 500;
const int MOD = 1000000007;
int main()
{
// freopen("in.txt", "r", stdin);
int t;
__int64 ans, n, k, num, buf;
scanf("%d", &t);
while(t --)
{
scanf("%I64d%I64d", &n, &k);
buf = k * (1 + k);
if(n < buf / 2) ans = -1;
else
{
num = n / k;
if(k % 2 == 0)
{
int ran = 1, coe = 1, sum = 0, form;
ans = 1;
while(1)
{
if(k == 1) break;
form = (num + ran * coe);
ans *= form;
sum += form;
if(ans > 1000000000) ans = ans % MOD;
coe *= -1;
k --;
if(k % 2 == 0) ran ++;
}
int res;
res = n - sum;
ans *= res;
if(ans > 1000000000) ans = ans % MOD;
}
else
{
int ran = 1, coe = 1, sum = num, form;
ans = num;
k = k - 1;
while(1)
{
if(k == 1) break;
form = (num + ran * coe);
ans *= form;
sum += form;
if(ans > 1000000000) ans = ans % MOD;
coe *= -1;
k --;
if(k % 2 == 0) ran ++;
}
int res;
res = n - sum;
ans *= res;
if(ans > 1000000000) ans = ans % MOD;
}
}
printf("%I64d\n", ans);
}
return 0;
}