C
题意:给你一个整数N,设N的长度为t,t个数字里选p个数字作为a,剩下t - p个数字作为b,要求a和b均大于0,且a和b不存在前导0,问能够获得的最大的a*b是多少
方法:全排列+暴力
#include<iostream>
#include<string>
using namespace std;
const int N = 20;
string n;
int st[N];
int ans;
void dfs(int u, string t){
if(u == n.size()){
for(int i = 1; i < n.size(); i ++){
string a = t.substr(0, i);
string b = t.substr(i);
if(a[0] == '0' || b[0] == '0') return;
int p = stoi(a), q = stoi(b);
ans = max(ans, p * q);
}
return;
}
for(int i = 0; i < n.size(); i ++){
if(st[i] == 0){
st[i] = 1;
dfs(u + 1, t + n[i]);
st[i] = 0;
}
}
}
int main(){
cin >> n;
dfs(0, "");
cout << ans;
}
D
题意:有N个人,每个人有一个登入时间a和在线天数b,分别输出同时在线人数为1,2,..., N的天数
这题最少做了3遍,每次都不会,这次记住了,一开始用二分离散化+差分wa到怀疑人生,然而这题做法比较特定,将每个人登入的时间(这个人在线的第一天),和他离线的时间(a + b)放到同一个序列里面并打标记
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
const int N = 200010;
#define PII pair<int, int>
int n;
vector<PII> v;
int ans[N];
int main(){
cin >> n;
for(int i = 0; i < n; i ++){
int a, b;
cin >> a >> b;
v.push_back({a, 1});
v.push_back({a + b, -1});
}
sort(v.begin(), v.end());
int cnt = 0;
for(int i = 0; i < v.size() - 1; i ++){
cnt += v[i].second;
ans[cnt] += v[i + 1].first - v[i].first;
}
for(int i = 1; i <= n; i ++) cout << ans[i] << ' ';
return 0;
}