AtCoder Beginner Contest 223
Posted MangataTS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Beginner Contest 223相关的知识,希望对你有一定的参考价值。
A - Exact Price
题意
你有一个或者多个100的硬币,问你是否能完整凑出X元
思路
直接取余就行,特判一下0的情况
CODE
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int a[N];
int t,n;
int main()
{
cin>>n;
if(n == 0) puts("No");
else {
if(n % 100 == 0) puts("Yes");
else puts("No");
}
return 0;
}
B - String Shifting
题意
给你一个字符串,你可以从该字符串的任意一个位置开始作为起始,然后以前一个位置为结束(将字符串想象成一个环),输出字典序最小的串和字典序最大的串
思路
- 因为数据很小所以我们可以暴力查找,复杂度为 O ( N 2 ) O(N_2) O(N2)
- 最小最大表示法,复杂度 O ( N ) O(N) O(N)
CODE
暴力
#include<bits/stdc++.h>
using namespace std;
int main()
{
string s;
cin>>s;
string mi=s;
string mx=s;
for(int i=0;i<s.length();++i)
{
string x=string(s,i,s.length())+string(s,0,i);
mi=min(mi,x);
mx=max(mx,x);
}
cout<<mi<<endl;
cout<<mx<<endl;
return 0;
}
最大最小表示法
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
char str[N];
int t,n;
int min_work()
{
int n = strlen(str);
int i = 0,j = 1, k = 0;
while(i<n && j<n && k<n)
{
int t = str[(i+k)%n] - str[(j+k)%n] ;
if(t == 0)
k++;
else
{
if(t>0)
i+=k+1;
else
j+=k+1;
if(i==j)
j++;
k = 0;
}
}
return i < j ? i : j;
}
int max_work() //最大表示法
{
int len = strlen(str);
int i=0,j=1,k=0;
while(i<len && j<len && k<len)
{
int t = str[(i+k)%len] - str[(j+k)%len];
if(!t) k++;
else
{
if(t>0) j = j+k+1;
else i = i+k+1;
if(i == j) j++;
k = 0 ;
}
}
return i<j?i:j;
}
int main()
{
cin>>str;
n = strlen(str);
int l1 = min_work();
int l2 = max_work();
for(int i = 0;i < n; ++i) {
putchar(str[l1]);
l1++;
l1 = l1 % n;
}
putchar('\\n');
for(int i = 0;i < n; ++i) {
putchar(str[l2]);
l2++;
l2 = l2 % n;
}
return 0;
}
C - Doukasen
题意
给你N段导火索,然后每段导火索的长度为 A i A_i Ai燃烧速度为 B i B_i Bi ,这N段导火索串联起来,然后再两端点燃,问你两团火相遇的时候距离左端点的距离是多少,至少保留五位小数
思路
先计算总共需要花费的时间,然后从左往右遍历过去,然后逐步计算即可
CODE
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
double a[N];
double b[N],c[N];
int t,n;
int main()
{
scanf("%d",&n);
double sum_time = 0;
for(int i = 0;i < n; ++i) {
scanf("%lf%lf",&a[i],&b[i]);
c[i] = a[i]/b[i];
sum_time += c[i];
}
sum_time/=2;
double sum_len = 0;
int i = 0;
for(;i < n; ++i) {
if(sum_time >= c[i]) {
sum_time -= c[i];
sum_len += a[i];
}
else
break;
}
sum_len += b[i] * sum_time;
printf("%.7lf\\n",sum_len);
return 0;
}
D - Restricted Permutation
题意
给你一个序列,找到满足条件的序列中字典序最小的序列
思路
拓扑排序
CODE
#include<bits/stdc++.h>
using namespace std;
const int N = 200009;
int n, m, in[N];
struct Node
{
int to, next;
} mp[N];
int head[N], num;
void add(int x, int y)
{
mp[++num].to = y;
mp[num].next = head[x];
head[x] = num;
}
bool find(int x, int y)
{
for (int i = head[x]; i; i = mp[i].next)
if (mp[i].to == y) return true;
return false;
}
void __sort()
{
priority_queue<int, vector<int>, greater<int>> que;
for (int i = 1; i <= n; ++i)
if (!in[i])
que.push(i);
if (que.size() == 0)
{
puts("-1");
return;
}
int ans[N]={0},cnt=0;
while (!que.empty())
{
int p = que.top();
que.pop();
ans[++cnt]=p;
for (int i = head[p]; i; i = mp[i].next)
{
int kk = mp[i].to;
if (--in[kk] == 0)
que.push(kk);
}
}
if(cnt == n){
for(int i=1;i<=cnt;++i)
{
if(i!=1)
putchar(' ');
printf("%d",ans[i]);
}
}
else
puts("-1");
}
int main()
{
scanf("%d %d", &n, &m);
memset(head,0,sizeof head);
memset(in,0,sizeof in);
for (int i = 0; i < m; ++i)
{
int x, y;
scanf("%d %d", &x, &y);
if (find(x, y) == 0)
add(x, y),in[y]++;
}
__sort();
return 0;
}
E - Placing Rectangles
题意
给你一个长为X,宽为Y的矩形,然后三个面积分别为A,B,C的形状任意的矩形,问你是否能再第一个矩形中放下后面三个矩形(实际分配的面积可以大于后三个),且不能重叠
思路
思路就是从边入手,首先当后三个面积大于X*Y的时候直接输出No,然后我们假设放入的第一个矩形就会占据X行或者X列,然后我们再分别对剩下的两个矩形进行讨论,详情看代码
附上官方的题解证明:https://atcoder.jp/contests/abc223/editorial/2801
CODE
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll a[4];
bool f(ll X,ll Y,ll B,ll C) {
if(X <= 0 || Y <= 0) return false;
if(
((B / X + ( B % X !=0) + C/X + (C % X != 0)) <= Y) ||
((B / Y + (B % Y != 0) + C / Y + (C % Y != 0)) <= X)
)
return true;
else return false;
}
int main()
{
ll X,Y;
cin>>X>>Y;
ll sum_area = 0;
for(int i = 1;i <= 3; ++i) {
cin>>a[i];
sum_area+=a[i];
}
if(sum_area > X * Y) {
puts("No");
return 0;
}
else {
bool fg = false;
fg |= f(X - a[1]/Y - (a[1] % Y != 0),Y,a[2],a[3]);
fg |= f(X - a[2]/Y - (a[2] % Y != 0),Y,a[1],a[3]);
fg |= f(X - a[3]/Y - (a[3] % Y != 0),Y,a[1],a[2]);
fg |= f(Y - a[1]/X - (a[1] % X != 0),X,a[2],a[3]);
fg |= f(Y - a[2]/X - (a[2] % X != 0),X,a[1],a[3]);
fg |= f(Y - a[3]/X - (a[3] % X != 0),X,a[1],a[2]);
if(fg) puts("Yes");
else puts("No");
}
return 0;
}
以上是关于AtCoder Beginner Contest 223的主要内容,如果未能解决你的问题,请参考以下文章
AtCoder Beginner Contest 115 题解