Codeforces Round #811 (Div. 3)
文章目录
A. Everyone Loves to Sleep
题意+思路: 很简单的模拟,找到与给定时间最接近的时间,算出时间差值就好。(但是注意当时相同,分不同以及转到第二天的情况)
特判多容易出错QAQ
int n,h,m;
void solve()
{
scanf("%d %d %d",&n,&h,&m);
int ansh=inf,ansm=inf;
for(int i=1;i<=n;i++){
int h1,m1;
scanf("%d %d",&h1,&m1);
int t1=0,t2=0;
if(h1<h){
if(m!=0){//特判1
t2=60-m+m1;
t1=23-h+h1+t2/60;
t2%=60;
}
else {
t1=24-h+h1;
t2=m1;
}
}
else if(h==h1){
if(m1>=m)t2=m1-m;//特判2
else {
t2=60-m+m1;
t1=23-h+h1+t2/60;
t2%=60;
}
}
else{
if(m<=m1){//特判3
t1=h1-h;
t2=m1-m;
}
else{
t2=60-m+m1;
t1=h1-1-h+t2/60;
t2%=60;
}
}
if(t1<ansh)//特判4
ansh=t1,ansm=t2;
else if(t1==ansh&&t2<ansm)
ansm=t2;
}
printf("%d %d\n",ansh,ansm);
return;
}
B. Remove Prefix
题意与思路: 每次删除最前面的一个数,使得留下来的数互不相同。找到最长的没有重复数字的后缀数组。
int n;
int a[N];
void solve()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
map<int,int>mp;
for(int i=n;i>=1;i--){
if(!mp[a[i]])mp[a[i]]++;
else {
printf("%d\n",i);
return;
}
}
printf("%d\n",0);
return;
}
C. Minimum Varied Number
题意与思路: 找到数位和是n的最小的数,那么首先要求数位最少,最后多个数参与则小的尽量放在前面。
int n;
const int N=2e5+10;
int a[N];
void solve()
{
int n;
scanf("%d",&n);
vector<int>v;
for(int i=9;i>=1;i--){
if(n>=i){
n-=i;
v.push_back(i);
}
else break;
}
v.push_back(n);
sort(v.begin(),v.end());
for(int i=0;i<v.size();i++){
if(v[i]==0)
continue;
else
printf("%d",v[i]);
}
printf("\n");
return;
}
D. Color with Occurrences
题意与思路: 给定多个字符串,能否将原字符串染色。将能够给原字符串染色的字符串存下来,因为可能存在字符串aba染色后,后面可能还会有ab,ba也能够将aba染色重复染色的情况,所以要避免。
挺好的模拟,得想清楚,当时没写出来QAQ
string s;
int n;
int length;
struct node{
int l,r,id;
};
bool check(int start, string t) {//判断目前字符串在原始字符串中能否染色
int maxn = length - start + 1;
if (maxn < t.size()) return 0;
for (int i = start, j = 0; j < (int)t.size(); ++i, ++j) {
if (t[j] != s[i]) return 0;
}
return 1;
}
void solve() {
int n;
cin >> s >> n;
vector<node>v;
length = s.size();
s = " " + s;
for (int i = 1; i <= n; ++i) {
string t;
cin >> t;
int len = t.size();
for (int j = 1; j <= length; ++j) {
if (check(j, t)) v.push_back({j, j + len - 1, i});
}
}
sort(v.begin(), v.end(),[](node a,node b){
if(a.l!=b.l)return a.l<b.l;
else return a.r<b.r;
});//排序,尽量让能够染色前面的字符串的在前面
bool flag = 0;
int start = 1, end = length;
vector<PII> ans;
for (int i = 0; i < v.size(); ++i) {
int j = i, r = -inf;
int t = 0;
while (j < v.size() && v[j].l <= start) {//尽量选择能够染色的最长的字符串
if (v[j].r > r){
r = v[j].r;
t = j;
}
j++;
}
if (r < start) break;
start = r+1,i = j-1;
ans.push_back({v[t].id,v[t].l});
if(r>= end){
flag = true;
break;
}
}
if(flag){
printf("%d\n",ans.size());
for(auto it:ans)
printf("%d %d\n",it.first,it.second);
}
else printf("-1\n");
}
E. Add Modulo 10
题意与思路: 每次可以对数进行操作,a+=a%10,那么最后能不能使得所有的数字相同。很显然有规律,当数结尾都是0、5时,0结尾最后还是原数,5结尾最后只能等于+5的数,直接判断相邻数是否相等。
结尾:
0:0 0 0 0 0 0 0 0 0......
1:1 2 4 8 6 2 4 8 6......
2:2 4 8 6 2 4 8 6 2......
3:3 6 2 4 8 6 2 4 8......
4:4 8 6 2 4 8 6 2 4......
5:5 0 0 0 0 0 0 0 0......
6:6 2 4 8 6 2 4 8 6......
7:7 4 8 6 2 4 8 6 2......
8:8 6 2 4 8 6 2 4 8......
9:9 8 6 2 4 8 6 2 4......
//观察规律很容易得到两个数将尾数统一之后的差值只能是20的整数倍
//需要注意奇数结尾先要将奇数变成偶数
const int N=2E5+10;
void solve()
{
int n;
scanf("%d",&n);
int a[N];
int flag1=0,flag2=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]%10==0||a[i]%10==5)flag1++;
else flag2++;
if(a[i]%10==5)a[i]+=5;
}
if(flag1&&flag2)puts("NO");
else if(!flag2){
for(int i=2;i<=n;i++){
if(a[i]!=a[i-1]){
puts("NO");
return;
}
}
puts("YES");
}
else{
int flag=1;
for(int i=1;i<n;i++){
int t=a[i];
if(a[i+1]%10&1)a[i+1]+=a[i+1]%10;
while(t%10!=a[i+1]%10)
t+=t%10;
if((max(t,a[i+1])-min(t,a[i+1]))%20!=0){
flag=0;
break;
}
}
if(flag)puts("YES");
else puts("NO");
}
}
总结
继续加油,努力,向前冲!!!