Atcoder Panasonic Programming Contest 2020 题解

A - Kth Term

模拟水题,复制粘贴即可

#include<bits/stdc++.h>
using namespace std;
#define maxn 1010
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);
#pragma GCC optimize(2)
#define ll long long
#define makefa(n) for(int i=1;i<=(n);i++)f[i]=i;
#define hh puts("");
int main(){
    int a[32]={1, 1, 1, 2, 1, 2, 1, 5, 2, 2, 1, 5, 1, 2, 1, 14, 1, 5, 1, 5, 2, 2, 1, 15, 2, 2, 5, 4, 1, 4, 1, 51};
    int k;
    cin>>k;
    cout<<a[k-1];
    return 0;
}

B - Bishop

看图差不多就能看出规律,奇数行的偶数位走不到,偶数行的奇数位走不到,但要注意特判1,h或w为1时只能是1个(蒟蒻就这wa了五发QAQ)

#include<bits/stdc++.h>
using namespace std;
#define maxn 1010
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);
#pragma GCC optimize(2)
#define ll long long
#define makefa(n) for(int i=1;i<=(n);i++)f[i]=i;
#define hh puts("");
int main(){
    ll h,w;
    cin>>h>>w;
    if(w==1||h==1){cout<<"1";return 0;}
    ll x=w/2,y=h/2;
    if(w%2!=0)x++;
    if(h%2!=0)y++;
    ll ans=x*y;
    ans+=(w-x)*(h-y);
    cout<<ans;
    return 0;
}

C - Sqrt Inequality

模拟水题,但是会卡double精度,一开始只把double换成了long double,没有两边平方,两边平方后sqrt/sqrtl求均可(感谢某位大佬指点)

#include<bits/stdc++.h>
using namespace std;
#define ld long double
int main()
{
	ios::sync_with_stdio(0);cin.tie(0);
	ld a,b,c;
	cin>>a>>b>>c;
	if(a+b+2*sqrtl(a*b)<c)cout<<"Yes";
	else cout<<"No";
}

D - String Equivalence

(早知道D这么水我就先做D了)
很明显的一道dfs题,求一个加了限制条件的全排列,对于第k位来说,当前位置最多能放的字母种类一定和之前的位置有关,如果前k-1位放了dif种字母,那么第k位就可以放dif+1种字母,dfs过程中记录dif就好.

#include<bits/stdc++.h>
using namespace std;
#define maxn 1010
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);
#pragma GCC optimize(2)
#define ll long long
#define makefa(n) for(int i=1;i<=(n);i++)f[i]=i;
#define hh puts("");
#define eps 1e-10
#define db double
int n;
int dif=0;
char s[maxn];
void dfs(int i){
    if(i==n+1){
        cout<<s+1<<endl;
        return;}
    for (int j = 0; j <=dif ; ++j) {
        s[i]='a'+j;
        int tmp=dif;
        if(j==dif)dif++;
        dfs(i+1);
        dif=tmp;
    }
}
int main(){
    cin>>n;
    dfs(1);
    return 0;
}

E - Three Substrings

dp题
答案可以通过计算a,b,c的相对位置得出,不妨固定a的首字母位置是0,那么b,c的首字母的位置可能是-4000~4000,遍历可能的位置并判断当前位置是否合法,遍历过程中更新答案即可。
怎么找合法位置,比如下图
忽略字体QAQ
对于a和b固定a的首字母位置为0,然后两个for判断匹配情况,如果a的第i个字符与b的第j个字符不匹配(不相同或者均不为’?’),那么b的首字母位置就是i-j+0,标记该位置记为不合法情况,依次处理ab,bc,ac(三个数组记录,图中分别是ab,bc,ac,即固定前者的情况下后者的相对位置)。

计算答案时,b相对位置为i,c相对位置为j,则c相对于b的位置为j-i(画图易得)

#include<bits/stdc++.h>
using namespace std;
#define maxn 2010
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);
#pragma GCC optimize(2)
#define ll long long
#define makefa(n) for(int i=1;i<=(n);i++)f[i]=i;
#define hh puts("");
#define eps 1e-10
#define db double
#define AC 2333
#define REP(i,n) for((i)=0;(i)<(n);(i)++)
bool ab[maxn+20000],ac[maxn+20000],bc[maxn+20000];
bool match(char c,char d){return c==d||c=='?'||d=='?';}
int main(){
   IOS
   string a,b,c;
   cin>>a>>b>>c;
   int i,j;
   int la=a.size(),lb=b.size(),lc=c.size();
   REP(i,la)REP(j,lb)if(!match(a[i],b[j]))ab[i-j+10000]=true;
    REP(i,la)REP(j,lc)if(!match(a[i],c[j]))ac[i-j+10000]=true;
    REP(i,lb)REP(j,lc)if(!match(b[i],c[j]))bc[i-j+10000]=true;
    int ans=3*maxn;
    for (i = -2*maxn; i <=2*maxn ; ++i) {
        for (j = -2*maxn;  j<=2*maxn ; j++) {
            if(!ab[i+10000] && !ac[j+10000] && !bc[j-i+10000]){
                int l=min(0,min(i,j));
                int r=max(la,max(lb+i,j+lc));
                ans=min(ans,r-l);
            }
        }
    }
    cout<<ans;
    return 0;
}

F - Fractal Shortest Path

貌似是分治,把作业赶完再来填坑(逃)

发布了1 篇原创文章 · 获赞 6 · 访问量 325

猜你喜欢

转载自blog.csdn.net/qq_43682148/article/details/104873271