#链接
https://atcoder.jp/contests/abc215/tasks
https://atcoder.jp/contests/abc215/tasks/abc215_a
签到水题。
给一个字符串,判断是否是 Hello,World!。
#include
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PLL;
const LL INF=4e18;
const int MAXN=1e6+10;
int main() {
#if 0
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#endif
#if 0
freopen("00.in", "r", stdin);
freopen("00.out", "w", stdout);
#endif
string s;
getline(cin, s);
if (s=="Hello,World!") {
cout<<"AC\n";
} else {
cout<<"WA\n";
}
return 0;
}
https://atcoder.jp/contests/abc215/tasks/abc215_b
给一个 n n n,找最大的整数 k k k,满足 2 k ≤ n 2^k \leq n 2k≤n。
由于本题的 n n n 很小,只有 1 0 18 10^{18} 1018,因此可以使用暴力求解。
#include
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PLL;
const LL INF=4e18;
const int MAXN=1e6+10;
int main() {
#if 1
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#endif
#if 0
freopen("00.in", "r", stdin);
freopen("00.out", "w", stdout);
#endif
LL n;
cin>>n;
LL k=0;
LL ans=1;
while (ans<=n) {
k++;
ans*=2;
}
cout<<k-1<<"\n";
return 0;
}
https://atcoder.jp/contests/abc215/tasks/abc215_c
给一个字符串 S S S,求第 K K K 小的字典序字符串。
本题的 S S S 长度只有 8 8 8,也就意味着最多是 8 ! = 40 , 320 8!=40,320 8!=40,320 种答案。因此,我们只需要列出所有的全排列,然后输出第 K K K 小的即可。
最简单的方法就是使用 STL 的 next_permutation() 函数。当然也可以使用 dfs 来解。
#include
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PLL;
const LL INF=4e18;
const int MAXN=1e5+10;
string ans[MAXN];
int main() {
#if 1
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#endif
#if 0
freopen("00.in", "r", stdin);
freopen("00.out", "w", stdout);
#endif
string s;
LL K;
cin>>s>>K;
sort(s.begin(), s.end());
LL cnt=0;
do {
ans[++cnt]=s;
//cout<
} while (next_permutation(s.begin(), s.end()));
//cout<
cout<<ans[K]<<"\n";
return 0;
}
https://atcoder.jp/contests/abc215/tasks/abc215_d
给 N N N 个正整数 A 1 , A 2 , … , A N A_1,\ A_2,\ \dots,\ A_N A1, A2, …, AN,找出所有从 1 1 1 到 k k k,满足 gcd ( A i , k ) = 1 \text{gcd}(A_i, k)=1 gcd(Ai,k)=1。
本题要求找出任意一个 k k k 和数组 A A A 的所有元素互质。
如果本题使用暴力求解,即枚举所有的 1 ∼ m 1 \sim m 1∼m 中的所有数据,使得其满足题目要求。但是由于 n , m n,\ m n, m 的大小为 1 0 5 10^5 105,这个算法的时间复杂度为 O ( m ∗ n ) O(m*n) O(m∗n),因此最大情况需要计算 1 0 5 ∗ 1 0 5 = 1 0 10 10^5 *10^5=10^{10} 105∗105=1010,这样的计算量即使是 2 2 2s 也是要超时的。
注意到本题的 A i A_i Ai 取值范围是 1 ∼ 1 0 5 1 \sim 10^5 1∼105,也就是说这个值域非常小。所以我们可以先用筛法筛出 1 0 5 10^5 105 中所有质数。然后再遍历 m m m。
#include
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PLL;
const int MAXN=1e5+10;
vector<bool> exist(MAXN, false);//数据i是否出现
vector<bool> ispri(MAXN, true);//数据i是否是质数
int main() {
#if 1
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#endif
#if 0
freopen("00.in", "r", stdin);
freopen("00.out", "w", stdout);
#endif
LL n,m;
cin>>n>>m;
//筛法初始化
ispri[0]=ispri[1]=false;//质数
for (LL i=1; i<=n; i++) {
LL val;
cin>>val;
exist[val]=true;
}
//找出范围内所有质数
for (LL i=2; i<MAXN; i++) {
if (!ispri[i]) {
exist[i]=false;
continue;
}
for (LL j=i; j<MAXN; j+=i) {
ispri[j]=false;
if (exist[j]) {
exist[i]=true;
break;
}
}
}
//遍历可能的结果
vector<bool> possible(m+1, true);
possible[0]=false;
for (LL i=2; i<=m; i++) {
if (!exist[i]) {
continue;
}
for (LL j=i; j<=m; j+=i) {
possible[j]=false;
}
}
LL cnt=0;
for (LL i=1; i<=m; i++) {
if (possible[i]) {
cnt++;
}
}
cout<<cnt<<"\n";
for (LL i=1; i<=m; i++) {
if (possible[i]) {
cout<<i<<"\n";
}
}
return 0;
}
https://atcoder.jp/contests/abc215/tasks/abc215_e
这题是竞赛后完成的。阅读完后,这题是一个 bit DP 题目。惨,bit DP 早就忘记了。还好,本题算 bit DP 的模板题,直接套用模板即可。
对应的状态方程如下:
d p [ i ] [ u ] [ j ] = d p [ i − 1 ] [ u ] [ j ] dp[i][u][j]=dp[i-1][u][j] dp[i][u][j]=dp[i−1][u][j]
其中: i i i 表示竞赛的编号, u u u 表示所有的集合, j j j 表示竞赛的种类。
#include
using namespace std;
typedef long long LL;
const int MAXN=1024;
LL dp[MAXN][MAXN][12];
const LL MOD=998244353;
int main(){
#if 1
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#endif
LL n;
string s;
cin>>n>>s;
for(LL i=1;i<=n;i++){
LL x=s[i-1]-'A';
for(LL u=0; u<MAXN;u++){
for(LL j=0;j<10;j++){
dp[i][u][j]=dp[i-1][u][j];
if(j==x){
dp[i][u][j]+=dp[i-1][u][j];
dp[i][u][j]%=MOD;
}
}
}
for(LL v=0;v<MAXN;v++){
if(v&(1<<x)){
continue;
}
for(LL j=0;j<10;j++){
dp[i][v|(1<<x)][x]+=dp[i-1][v][j];
dp[i][v|(1<<x)][x]%=MOD;
}
}
dp[i][(1<<x)][x]++;
dp[i][(1<<x)][x]%=MOD;
}
LL res=0;
for(LL u=0;u<MAXN;u++){
for(LL j=0;j<10;j++){
res+=dp[n][u][j];
res%=MOD;
}
}
cout << res << '\n';
return 0;
}
https://atcoder.jp/contests/abc215/tasks/abc215_f
吐槽一下,F 题竟然比 E 题简单。
题目要求我们找所有最大问题的最小值,直接使用二分答案即可。
根据题目可知: min ( ∣ x i − y i ∣ , ∣ x j − y j ∣ ) ≥ K → ∣ x i − y i ∣ ≥ K && ∣ x j − y j ∣ ≥ K \text{min}(|x_i-y_i|,\ |x_j-y_j|) \geq K \rightarrow |x_i-y_i| \geq K\ \text{\&\&}\ |x_j-y_j| \geq K min(∣xi−yi∣, ∣xj−yj∣)≥K→∣xi−yi∣≥K && ∣xj−yj∣≥K。
#include
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PLL;
const LL INF=4e18;
int main(){
#if 1
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#endif
LL n;
cin >> n;
vector<PLL> v(n);
for (LL i = 0; i < n; i++) {
cin >> v[i].first >> v[i].second;
}
sort(v.begin(), v.end());
LL ok = 0, ng = INF;
while(ng - ok > 1){
LL md = (ok + ng)/2;
queue<PLL> que;
bool able = false;
LL mi = INF, ma = 0;
for (auto p:v){
while(!que.empty()){
if(que.front().first > p.first - md) {
break;
}
mi = min(mi, que.front().second);
ma = max(ma, que.front().second);
que.pop();
}
if(mi <= p.second - md || ma >= p.second + md) {
able=true;
}
que.push(p);
}
if(able) {
ok = md;
} else {
ng = md;
}
}
cout << ok << endl;
return 0;
}
我太难了,所有的东西都忘记了。人生艰难,连 ABC 都没法 AK 了。惨。