题目链接
A - Not
思路:
无
代码:
/*
* @Author : nonameless
* @Date : 2020-09-13 19:55:56
* @LastEditors : nonameless
* @LastEditTime : 2020-09-13 20:00:55
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define sz(x) (int)x.size()
#define toStr(name) (#name)
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PLL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const double eps = 1e-6;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b,a % b):a;}
inline ll gcd(ll a, ll b) { return b ? gcd(b,a % b):a;}
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
template<class T>
inline void read(T &x){
x = 0;
int f = 1;
char c = getchar();
while(c < '0' || c > '9') if(c == '-') { f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
x = x * f;
}
template<class T>
inline void out(string a, T x){ cout << a << " = " << x << endl; }
int main(){
int x; read(x);
if(x == 0) puts("1");
if(x == 1) puts("0");
return 0;
}
B - Product Max
思路:
显然答案只会出现在端点的相乘上,所以暴力枚举出四种情况取 (max) 即可。
代码:
/*
* @Author : nonameless
* @Date : 2020-09-13 20:02:06
* @LastEditors : nonameless
* @LastEditTime : 2020-09-14 00:51:31
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define sz(x) (int)x.size()
#define toStr(name) (#name)
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PLL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const double eps = 1e-6;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b,a % b):a;}
inline ll gcd(ll a, ll b) { return b ? gcd(b,a % b):a;}
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
template<class T>
inline void read(T &x){
x = 0;
int f = 1;
char c = getchar();
while(c < '0' || c > '9') if(c == '-') { f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
x = x * f;
}
template<class T>
inline void out(string a, T x){ cout << a << " = " << x << endl; }
int main(){
ll a, b, c, d; cin >> a >> b >> c >> d;
ll ans = -LNF;
ans = max(ans, a * c);
ans = max(ans, a * d);
ans = max(ans, b * c);
ans = max(ans, b * d);
cout << ans << endl;
return 0;
}
C - Ubiquity
思路:
直接考虑不方便,所以我们考虑不合法的方案数。
先用快速幂算出 (10^n) 即总方案数。
然后枚举不合法的情况:
- 只有 (0) 的情况:(sum_{i=1}^nC_n^i imes 8^{n-i})。((i) 是 (0) 出现的个数)
- 只有 (9) 的情况:与 (0) 的一样
- 没有 (0, 9) 的情况:(8^n)。
然后减去上述情况即可。
代码:
/*
* @Author : nonameless
* @Date : 2020-09-13 20:14:14
* @LastEditors : nonameless
* @LastEditTime : 2020-09-13 20:38:55
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define sz(x) (int)x.size()
#define toStr(name) (#name)
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PLL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const double eps = 1e-6;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b,a % b):a;}
inline ll gcd(ll a, ll b) { return b ? gcd(b,a % b):a;}
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
template<class T>
inline void read(T &x){
x = 0;
int f = 1;
char c = getchar();
while(c < '0' || c > '9') if(c == '-') { f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
x = x * f;
}
template<class T>
inline void out(string a, T x){ cout << a << " = " << x << endl; }
const int mod = 1e9 + 7;
const int N = 1e6 + 10;
ll f[N];
ll qpow(ll a, ll b){
ll res = 1;
while(b){
if(b & 1) res = res * a % mod;
b >>= 1;
a = a * a % mod;
}
return res;
}
ll C(ll a, ll b){
return f[a] * (qpow(f[b] * f[a - b] % mod, mod - 2)) % mod;
}
int main(){
f[0] = 1;
for(int i = 1; i < N; i ++) f[i] = f[i - 1] * i % mod;
ll n; read(n);
if(n == 1) puts("0");
else{
ll ans = qpow(10, n);
ll t1 = 0;
for(int i = 1; i <= n; i ++){
t1 = (t1 + C(n, i) * qpow(8, n - i) * 2 % mod) % mod;
}
t1 = (t1 + qpow(8, n)) % mod;
ans = (ans - t1 + mod) % mod;
cout << ans << endl;
}
return 0;
}
D - Redistribution
思路:
设 (f[i][j]) :长度为 (i) 且和为 (j) 的序列的个数。
那么转移方程有:(f[i][j] = f[i][j] + f[i-1][j-k](3leq kleq j))
但是这样枚举是有三重循环,显然超时,所以考虑优化掉一重循环。
观察方程可以发现 (f[i-1][j-k]) 是可以用前缀和求出来的,因为他就是上一层计算出来的,所以我们可以在处理完 (i) 的时候,求出当前长度的前缀和供下一层使用。
注意边界的初始化。对长度为 (0) 的也要求一次前缀和。
代码:
/*
* @Author : nonameless
* @Date : 2020-09-13 20:40:53
* @LastEditors : nonameless
* @LastEditTime : 2020-09-14 00:59:44
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define sz(x) (int)x.size()
#define toStr(name) (#name)
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PLL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const double eps = 1e-6;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b,a % b):a;}
inline ll gcd(ll a, ll b) { return b ? gcd(b,a % b):a;}
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
template<class T>
inline void read(T &x){
x = 0;
int f = 1;
char c = getchar();
while(c < '0' || c > '9') if(c == '-') { f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
x = x * f;
}
template<class T>
inline void out(string a, T x){ cout << a << " = " << x << endl; }
const int N = 2e3 + 10;
const int mod = 1e9 + 7;
int f[N / 3][N];
int main(){
int s; read(s);
ll ans = 0;
f[0][0] = 1;
for(int i = 1; i <= s; i ++) f[0][i] = 1;
for(int i = 1; i <= s / 3; i ++){
for(int j = 3; j <= s; j ++){
f[i][j] = (f[i][j] + f[i - 1][j - 3]) % mod;
ans = (ans + f[i][s]) % mod;
}
for(int j = 1; j <= s; j ++) f[i][j] = (f[i][j] + f[i][j - 1]) % mod;
}
cout << ans << endl;
return 0;
}
E - Dist Max
思路:
这其实就是一个最远曼哈顿距离的模板题(奈何我不知道)。
由:(|a - b| = max(a - b, b - a));
那么可以将 (|x_i-x_j|+|y_i-y_j|) 变为在下面四种情况中取 (max) :
- ((x_i-x_j) + (y_i-y_j))
- ((x_i-x_j)+(y_j-y_i))
- ((x_j-x_i)+(y_i-y_j))
- ((x_j-x_i)+(y_j-y_i))
我们利用交换律将一个点的坐标放在一起:
- ((x_i+y_i)+(-x_j-y_j))
- ((x_i-y_i)+(-y_i+y_j))
- ((-x_i+y_i)+(x_j-y_j))
- ((-x_i-y_i)+(x_j+y_j))
我们可以发现其实就只有两种情况了((1,4) 是一种情况,(2, 3) 是一种情况)即:
- ((x_i+y_i)+(-x_j-y_j))
- ((x_i-y_i)+(-y_i+y_j))
代码:
/*
* @Author : nonameless
* @Date : 2020-09-14 00:38:45
* @LastEditors : nonameless
* @LastEditTime : 2020-09-14 00:45:05
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define sz(x) (int)x.size()
#define toStr(name) (#name)
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PLL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const double eps = 1e-6;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b,a % b):a;}
inline ll gcd(ll a, ll b) { return b ? gcd(b,a % b):a;}
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
template<class T>
inline void read(T &x){
x = 0;
int f = 1;
char c = getchar();
while(c < '0' || c > '9') if(c == '-') { f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
x = x * f;
}
template<class T>
inline void out(string a, T x){ cout << a << " = " << x << endl; }
vector<int> v1, v2, v3, v4;
bool cmp(int a, int b) { return a > b; }
int main(){
int n; read(n);
for(int i = 1; i <= n; i ++){
int x, y;
read(x); read(y);
v1.pb(x + y);
v2.pb(-x - y);
v3.pb(-x + y);
v4.pb(x - y);
}
sort(all(v1), cmp); sort(all(v2), cmp); sort(all(v3), cmp); sort(all(v4), cmp);
int ans = max(v1[0] + v2[0], v3[0] + v4[0]);
cout << ans << endl;
return 0;
}