SCAU2021春季个人排位赛第八场 (部分题解)

A:签到
B:高斯消元模板题,但我自己好像也没读懂题意
C:hash+暴力枚举C的长度(哈希base要以10,卡模数1e9+7被卡了)
D:边双连通缩点+树直径
E:组合数学+DP
F:思维
G:模拟

 

A题

CodeForces - 49D 

Vasya and Petya have invented a new game. Vasya takes a stripe consisting of 1 × n square and paints the squares black and white. After that Petya can start moves — during a move he may choose any two neighboring squares of one color and repaint these two squares any way he wants, perhaps in different colors. Petya can only repaint the squares in white and black colors. Petya’s aim is to repaint the stripe so that no two neighboring squares were of one color. Help Petya, using the given initial coloring, find the minimum number of moves Petya needs to win.

Input

The first line contains number n (1 ≤ n ≤ 1000) which represents the stripe’s length. The second line contains exactly n symbols — the line’s initial coloring. 0 corresponds to a white square, 1 corresponds to a black one.

Output

If Petya cannot win with such an initial coloring, print -1. Otherwise print the minimum number of moves Petya needs to win.

Examples

Input

6
111010

Output

1

Input

5
10001

Output

1

Input

7
1100010

Output

2

Input

5
00100

Output

2

Note

In the first sample Petya can take squares 1 and 2. He repaints square 1 to black and square 2 to white.

In the second sample Petya can take squares 2 and 3. He repaints square 2 to white and square 3 to black.

 

这题解法我不会证明,一开始因为试错了所以没继续往那个方向想。后来再试了试才交了。

对于一个串,我们要么变成101010101010……,要么变成010101010101……。

拿原串和相同长度的10串和相同长度的01串一一比对,统计最小的不同的数量。

 

代码:

#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <cstring>
#include <string.h>
#include <math.h>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <list>

using namespace std;

int n,ans2,ans1;
string st;
int  a[1003],ai,b[1003],s[1003];
void ready()
{
    ios::sync_with_stdio(false),cin.tie(0);
    cin>>n;
    cin>>st;
    for(int i=0;i<n;i++)
        s[i]=st[i]-'0';
    for(int i=0;i<n;i+=2)
        a[i]=1;
    for(int i=1;i<n;i+=2)
        b[i]=1;
}
//110010 001001 000110

int main()
{
    ready();
    for(int i=0;i<n;i++)
    {
        if(s[i]!=a[i])
            ans1++;
        if(s[i]!=b[i])
            ans2++;
    }
    cout<<min(ans1,ans2);
    return 0;
}

 

 

F题

CodeForces - 111D 

Volodya and Vlad play the following game. There are k pies at the cells of n  ×  m board. Each turn Volodya moves one pie to the neighbouring (by side) cell. If the pie lies at the border of the board then Volodya can move it outside the board, get the pie and win. After Volodya's move, Vlad bans some edge at the border of the board of length 1 (between two knots of the board) so that Volodya is not able to move the pie outside the board through this edge anymore. The question is: will Volodya win this game? We suppose both players follow the optimal strategy.

Input

First line contains 3 integers, separated by space: 1 ≤ n, m ≤ 100 — dimensions of the board and 0 ≤ k ≤ 100 — the number of pies. Each of the next k lines contains 2 integers, separated by space: 1 ≤ x ≤ n, 1 ≤ y ≤ m — coordinates of the corresponding pie. There could be more than one pie at a cell.

Output

Output only one word: "YES" — if Volodya wins, "NO" — otherwise.

Examples

Input

2 2 1
1 2

Output

YES

Input

3 4 0

Output

NO

Input

100 50 2
50 25
50 25

Output

NO

 

题意:

n*m棋盘里有k个棋子。你可以向四个方向移动它。当你移动它出边界的时候,它就是你的了,你就赢了。

但是你每走一步,另一个人就会在边界放一个隔板。你的棋子走不出隔板。

所以问,当大家都用最优策略的时候,你有没有把握赢。

 

这题是个思维题。要想到,你在边缘走,我要堵你,肯定你走一格,把那格的边缘给堵住不让你跳下去。知道你一直往前走,走到角落,即使我堵了你一边,你可以从另一边掉下去。

所以就发现,你想跳出边界的关键点,就是四个角落

只要在你走到边界之前将四个角落都先堵上一片先,那么无论如何你都走不出去啦。

所以就是要看,最早跳出边界的棋子,也就是直线走最短次数要多少步。如果走到边缘是第5步,则前4步已经完全封好了四个角落了。没办法逃了。

 

代码:

#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <cstring>
#include <string.h>
#include <math.h>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <list>

using namespace std;

int n,m,k;
int x[105],y[105];

void ready()
{
    ios::sync_with_stdio(false),cin.tie(0);
    cin>>n>>m>>k;
    for(int i=1;i<=k;i++)
    {
        cin>>x[i]>>y[i];
    }
}

bool check()
{
    for(int i=1;i<=k;i++)
    {
        if(x[i]==n || y[i]==m || x[i]==1 || y[i]==1 || x[i]==2 || y[i]==2 || x[i]==3 || y[i]==3 || x[i]==4 || y[i]==4 || x[i]==5 || y[i]==5)
            return true;
        if((x[i]==n-1) || (y[i]==m-1) || (x[i]==n-2) || (y[i]==m-2) || x[i]==n-3 || y[i]==m-3 || x[i]==n-4 || y[i]==m-4)
            return true;
    }
    return false;
}

int main()
{
    ready();
    if(!check())
        cout<<"NO";
    else
        cout<<"YES";
    return 0;
}

 

G题

CodeForces - 21A 

Jabber ID on the national Berland service «Babber» has a form <username>@<hostname>[/resource], where

  • <username> — is a sequence of Latin letters (lowercase or uppercase), digits or underscores characters «_», the length of <username> is between 1 and 16, inclusive.
  • <hostname> — is a sequence of word separated by periods (characters «.»), where each word should contain only characters allowed for <username>, the length of each word is between 1 and 16, inclusive. The length of <hostname> is between 1 and 32, inclusive.
  • <resource> — is a sequence of Latin letters (lowercase or uppercase), digits or underscores characters «_», the length of <resource> is between 1 and 16, inclusive.

The content of square brackets is optional — it can be present or can be absent.

There are the samples of correct Jabber IDs: mike@codeforces.com, 007@en.codeforces.com/contest.

Your task is to write program which checks if given string is a correct Jabber ID.

Input

The input contains of a single line. The line has the length between 1 and 100 characters, inclusive. Each characters has ASCII-code between 33 and 127, inclusive.

Output

Print YES or NO.

Examples

Input

mike@codeforces.com

Output

YES

Input

john.smith@codeforces.ru/contest.icpc/12

Output

NO

 

垃圾英语害我一生。

就一个很普通的暴力模拟而已。

在<hostname>我一直以为,是用 ‘.’ 分割的字符子串。这个 ‘.’ 是肯定存在的,一直WA。再读题也一直以为这个点是在的。明明题目说是用period来separate的嘛,要分开肯定要有 ‘.’ 。然后现在查翻译“<hostname>-是由句点(字符)分隔的单词序列«.»), 如果每个单词只能包含<username>允许的字符,则每个单词的长度介于1和16之间(包括1和16)。<hostname>的长度介于1和32之间(含1和32)。”每个单词,每个。一个就不用点了。

代码:

#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <cstring>
#include <string.h>
#include <math.h>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <list>

using namespace std;

string s;
int l;

void ready()
{
    ios::sync_with_stdio(false),cin.tie(0);
    cin>>s;
    l=s.size();
}

bool ook(char c)
{
   return ( (c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='_'    );

}
//qq@q.com/df/55
bool check()
{
    int u=0,r=-1;
    for(int i=0;i<l;i++)
    {
        if(s[i]=='@')
        {
            u=i;
            break;
        }
    }
    if(u>=16 || u==0)
        return false;
    for(int i=0;i<u;i++)
    {
        if(!ook(s[i]))
          return false;
    }
    int cnt=0,p=0,pi=0;
    for(int i=u+1;i<l;i++)
    {
        if(s[i]=='/')
        {
            r=i;break;
        }
        cnt++;
        if(s[i]=='.')
        {
            if(p==0)
                return false;
            p=0;pi++;
            continue;
        }
        p++;
        if(cnt>32)
            return false;
        if(p>16)
            return false;
        if(!ook(s[i]))
            return false;
    }

    if(cnt==0 || p==0 )
        return false;
    if(r==-1)
        return true;
    cnt=0;
    for(int i=r+1;i<l;i++)
    {
        cnt++;
        if(cnt>16)
            return false;
        if(!ook(s[i]))
            return false;
    }
    if(cnt==0)
      return false;
    return true;
}

int main()
{
    ready();
    if(check())
      cout<<"YES";
    else
      cout<<"NO";
    return 0;
}

 

 

现在做的题大部分都是CF的题,为什么训练时做得这么慢?没得翻译呀平常打CF直接翻译就OK了。害。英语问题。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值