CodeForces 1072 A/B/C/D - [待补]

链接:http://codeforces.com/contest/1072/problem


A - Golden Plate - [计算题]

#include<bits/stdc++.h>
using namespace std;
inline int calc(int w,int h){return (w+h-2)*2;}
int w,h,k;
int ans;
int main()
{
    cin>>w>>h>>k;
    for(;w&&h&&k;w-=4,h-=4,k--) ans+=calc(w,h);
    cout<<ans<<endl;
}

B - Curiosity Has No Limits - [DFS]

对于常数 $C_1,C_2$ 和变量 $x,y$ 的方程组:

$\left\{ {\begin{array}{*{20}c} {C_1 = x|y} \\ {C_2 = x\& y} \\ \end{array}} \right.$

除了 $x$ 和 $y$ 之间能互换一下之外,其实解是唯一的。

因此,说是从 $1$ 到 $n$ 的深搜,其实只是 $O(n)$ 的枚举,因为当你确定了第一个数字 $t[1]$ 之后,后面的跟着都是确定的,因此只会DFS只会跑一条深度为 $n$ 的链。

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int maxn=1e5+50;

int n;
pii a[maxn],b[maxn];
pii cho[4];
bool judge(pii a,pii b,pii x,pii y)
{
    if((x.first|y.first)!=a.first || (x.second|y.second)!=a.second) return 0;
    if((x.first&y.first)!=b.first || (x.second&y.second)!=b.second) return 0;
    return 1;
}

bool ok;
int c[maxn];
void dfs(int d,int p)
{
    if(ok) return;
    if(d==n+1)
    {
        ok=1;
        return;
    }
    for(int i=0;i<=3;i++)
    {
        if(judge(a[d-1],b[d-1],cho[p],cho[i]))
        {
            c[d]=i;
            dfs(d+1,i);
        }
    }
}

int main()
{
    cho[0]=make_pair(0,0);
    cho[1]=make_pair(0,1);
    cho[2]=make_pair(1,0);
    cho[3]=make_pair(1,1);
    cin>>n;
    for(int i=1,k;i<n;i++)
    {
        scanf("%d",&k);
        a[i].first=k/2;
        a[i].second=k%2;
    }
    for(int i=1,k;i<n;i++)
    {
        scanf("%d",&k);
        b[i].first=k/2;
        b[i].second=k%2;
    }

    ok=0;
    for(int i=0;i<=3;i++)
    {
        c[1]=i;
        dfs(2,i);
        if(ok) break;
    }
    if(ok)
    {
        printf("YES\n");
        for(int i=1;i<=n;i++) printf("%d ",c[i]);
        printf("\n");
    }
    else printf("NO\n");
}

C - Cram Time - [暴力]

(忍不住想说,我队友太强了,跟他组队是我拖后腿了55555)

显然,要放最多的数进去,肯定是放 $1 \sim n$,其中 $n$ 是满足 $\frac{{\left( {n + 1} \right)n}}{2} \le a + b$ 的最大整数。

考虑第一天看 $a$ 的书,我们从最大的 $n$ 枚举起,遇到能塞得下的就往里塞,这样必然可以让第一天的 $a$ 个小时被占满,

而剩下的全部放到第二天就行了,剩下的那些加起来必然不会超过 $b$ 小时。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=63300;

ll a,b;
ll n;
bool vis[maxn];

int main()
{
    cin>>a>>b;
    for(n=0;n<maxn;n++) if((n+1)*n/2<=a+b && (n+2)*(n+1)/2>a+b) break;

    memset(vis,0,sizeof(vis));
    int cnt=0;
    for(int i=n;i>=1;i--)
    {
        if(a>=i)
        {
            vis[i]=1;
            a-=i;
            cnt++;
        }
    }

    printf("%d\n",cnt);
    for(int i=1;i<=n;i++) if(vis[i]) printf("%d ",i);
    printf("\n");
    printf("%d\n",n-cnt);
    for(int i=1;i<=n;i++) if(!vis[i]) printf("%d ",i);
    printf("\n");
}

D - Minimum path - [待补]

猜你喜欢

转载自www.cnblogs.com/dilthey/p/9826351.html