题目链接:Dashboard - Codeforces Round 861 (Div. 2) - Codeforces
A - Lucky Numbers
解题思路:大于100就直接输出最大值,小于的话就暴力一下。
#include
using namespace std;
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)|1
typedef long long ll;
using ull = unsigned long long;
const int mx = 1e5 + 10;
const int mod = 1e9 + 7;
int main() {
auto solve = [](int x) {
int mi = 100, ma = -1;
while (x) {
int v = x % 10;
ma = max(ma, v);
mi = min(mi, v);
x /= 10;
}
return ma - mi;
};
int t;
scanf("%d", &t);
while(t--) {
int l, r;
scanf("%d%d", &l, &r);
if (r - l >= 100) {
int v = l / 100 * 100 + 90;
if (v < l)
printf("%d\n", v + 100);
else
printf("%d\n", v);
continue;
}
int ans = -1,p;
while (l <= r) {
int val = solve(l);
if (ans < val) {
ans = val;
p = l;
}
l++;
}
printf("%d\n", p);
}
return 0;
}
B - Playing in a Casino
解题思路:按列进行排序,然后算一下每个数的正负值贡献
#include
using namespace std;
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)|1
typedef long long ll;
using ull = unsigned long long;
const int mx = 3e5 + 10;
const int mod = 1e9 + 7;
vector vec[mx];
int main() {
auto solve = [](int x) {
int mi = 100, ma = -1;
while (x) {
int v = x % 10;
ma = max(ma, v);
mi = min(mi, v);
x /= 10;
}
return ma - mi;
};
int t;
scanf("%d", &t);
while(t--) {
int n,m,v;
scanf("%d%d", &n, &m);
for (int i=1;i<=m;i++)
vec[i].clear();
for (int i=1;i<=n;i++) {
for (int j=1;j<=m;j++) {
scanf("%d", &v);
vec[j].push_back(v);
}
}
ll sum = 0;
for (int i=1;i<=m;i++) {
sort(vec[i].begin(), vec[i].end());
for (int j=0; j
C - Unlucky Numbers
解题思路:暴力枚举+剪枝。
#include
using namespace std;
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)|1
typedef long long ll;
using ull = unsigned long long;
const int mx = 3e5 + 10;
const int mod = 1e9 + 7;
ll n,m;
ll tens[20];
ll val;
bool check(ll v, int mi, int ma, int p, bool f1, bool f2)
{
if (v > m || v + tens[p] - 1 < n)
return false;
if (p == 0) {
val = v;
return f1 && f2;
}
for (int i=mi; i<=ma; i++) {
if (check(v + i * tens[p-1], mi, ma, p - 1, f1 | (i==mi), f2 | (i==ma)))
return true;
}
return false;
}
int main() {
auto solve = [](int &ans, ll &ret, int i) {
for (int j=0; j m)
break;
for (int k=max(1,mi_k); k<=mi_k+j; k++) {
if (k * tens[i] > m)
break;
//printf("%d %d\n", k*tens[i], i);
// 当前值,最小值,最大值,还有的位数,最小值满足,最大值满足
if (check(k*tens[i], mi_k, mi_k+j, i, k==mi_k, k==mi_k+j)) {
ret = val;
ans = j;
return;
}
}
}
}
};
tens[0] = 1;
for (int i=1;i<=18;i++) {
tens[i] = tens[i-1] * 10;
}
tens[19] = 2 * tens[18];
int t;
scanf("%d", &t);
while(t--) {
scanf("%lld%lld", &n, &m);
int ans = 10;
ll ret;
for (int i=0;i<=18;i++) {
if (tens[i] > m)
break;
if (tens[i+1] - 1 < n)
continue;
solve(ans, ret, i);
}
printf("%lld\n", ret);
}
return 0;
}
D - Petya, Petya, Petr, and Palindromes
解题思路:算一下不需要修改的对数,然后用总共的对数减去不需要修改的对数就是答案了,不需要修改也就是两个位置数相同,因为k是奇数,所以我们分开讨论偶数的位置和奇数的位置相同数的贡献就行了。
#include
using namespace std;
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)|1
typedef long long ll;
using ull = unsigned long long;
const int mx = 2e5 + 10;
const int mod = 1e9 + 7;
vector vec[2][mx];
int main() {
auto solve = [](int &ans, ll &ret, int i) {
};
int n, k, u;
scanf("%d%d", &n, &k);
ll sum = 1ll * k / 2 * (n - k + 1);
for (int i=1;i<=n;i++) {
scanf("%d", &u);
vec[i&1][u].push_back(i);
}
for (int i=1; i= d2)
sum -= (d1 - d2 + 1);
}
}
}
printf("%lld\n", sum);
return 0;
}
E1 - Minibuses on Venus (easy version)
解题思路:如果一组数最终和的模是k,那么要减去i之后模为i,那么2 * i = k (mod m)。可以分析出可能多个i只想同一个k。我们dp[i][j][k]表示获取i张牌之后这i张牌里面不包含2 * x = j(mod m)的数并且它的和对m求模等于k。那么我们最终只需要把总数减去dp[n][i][i](0~k)就行了,因为这些情况是不满足条件的,因为他没不包含2 * x = i(mod m)的数并且他们最终的模数还等于i。dp时间复杂度为O(n*k^3)
#include
using namespace std;
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)|1
typedef long long ll;
using ull = unsigned long long;
const int mx = 1e2 + 10;
const int mod = 1e9 + 7;
ll dp[mx][35][35];
ll ret[mx][35];
ll res[35];
int main() {
auto solve = [](int &ans, ll &ret, int i) {
};
int n, k, m;
scanf("%d%d%d",&n,&k,&m);
ret[0][0] = 1;
for (int i=0;i
E2 - Minibuses on Venus (medium version)
解题思路:我们可以把每次枚举一张牌看做是多项式卷积,枚举x,令2 * i = x (mod k)的数的项数为零,其他位置为1,那么就可以像E1那样求得n个数最终模数是x但是里面不包含2 * i = x (mod k)的情况了,最终用总数减去就行了。所以这里面需要用到快速幂来解决,因为每次卷积的式子是一样的,所以可以使用快速幂,并且卷积方式也满足快速幂乘法要求。最终时间复杂度为O(logn*k^3)
#include
using namespace std;
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)|1
typedef long long ll;
using ull = unsigned long long;
const int mx = 1e2 + 10;
const int mod = 1e9 + 7;
int m;
class MultiData {
public:
vector v;
MultiData (int k, int val) {
v = vector (k, val);
}
MultiData operator * (const MultiData &A) const {
int k = v.size();
MultiData temp(k, 0);
for (int i=0;i>=1;
x = x * x % m;
}
return ans;
}
MultiData qmulti(MultiData &base, ll n, int k)
{
MultiData ans(k, 0);
ans.v[0] = 1;
while (n) {
if (n&1) ans = ans * base;
n >>= 1;
base = base * base;
}
return ans;
}
int main() {
auto solve = [](int &ans, ll &ret, int i) {
};
int k;
ll n;
scanf("%lld%d%d",&n,&k,&m);
ll ans = qpow(k, n);
for (int i=0;i