D
题意:
已知n个数,q次查询,使得 l <= i <= r, l <= j <= r, a[i] != a[j]
,如果能查询到这样的i和j, 则输出, 查询不到就输出-1 -1
每次找与自己的左边第一个不一样的数的位置即可
int n; cin >> n;
for(int i = 1; i <= n; i ++) cin >> a[i];
for(int i = 2; i <= n; i ++)
{
if(a[i] != a[i - 1])
l[i] = i - 1;
else l[i] = l[i - 1];
}
int q; cin >> q;
while(q --)
{
int ll, r; cin >> ll >> r;
if(l[r] >= ll) cout << l[r] << " " << r << endl;
else cout << "-1 -1" << endl;
}
E
题意:
给n个数, 保证1~n, 你给他排列一下,使得每连续k个数的总和相差都不会超过1, 也就是k个连续数的总和的max - min <= 1,已给n, k, 求这样的排列方式
我们可以知道, a,b, c, d, a + 1, b - 1, c + 1, d - 1.....这样的排列满足题意
也就是说 若 k = 4;
a1 + a2 + a3 + a4 = s1;
a2 + a3 + a4 + a5 = s2;
a3 + a4 + a5 + a6 = s3;
a4 + a5 + a6 + a7 = s4; ......
可得:
a5 - a1 = s2 - s1;
a6 - a2 = s3 - s2; ......
所以不妨设
s2 - s1 = 1; s3 - s2 = -1;
a5 - a1 = 1, a6 - a2 = -1, a7 - a3 = 1, a8 - a4 = -1....
也就是奇数加1,偶数减1
void solved()
{
int n, k; cin >> n >> k;
int ans = 1;
for(int i = 1; i <= k; i ++)
{
if(i % 2 == 1) //奇数加1
{
for(int j = i; j <= n; j += k)
a[j] = ans ++;
}
else //偶数减1
{
//找到最后一组完整的之后
//+i表示现在第几个
//如果超过范围就去上一组 -k
int st = n / k * k + i;
if(st > n) st -= k;
for(int j = st; j >= 1; j -= k)
a[j] = ans ++;
}
}
for(int i = 1; i <= n; i ++)
cout << a[i] << " ";cout << endl;
}