ARC078

C、D略

E
玩交互,中途发现看错2次题意….
这种猜数的交互一般都要二分,所以需要利用他的Y和N二分
先用1e9判N是不是10的若干次方,再用10^k询问找到N的位数,接着可以逐位二分了
注意确定到最后一位的时候要在后面加个0,否则不管最后一位填0~9,答案都会是Y(手测都没发现这个…结果交上去一直不过样例…

code:

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int maxn = 110;

void query(const ll x){cout<<'?'<<' '<<x<<endl;fflush(stdout);}
char ttt[maxn];
bool get_res(){cin>>ttt;return ttt[0]=='Y'?true:false;}
void answer(const ll x){cout<<'!'<<' '<<x<<endl;fflush(stdout);}

ll pw[maxn],pw9[maxn];
bool e[maxn],e9[maxn];

int main()
{
    //freopen("tmp.in","r",stdin);
    //freopen("tmp.out","w",stdout);

    ll l=1; for(int i=0;i<=10;i++,l*=10ll) pw[i]=l,query(l),e[i]=get_res();

    if(e[10])
    {
        l=9; for(int i=1;i<=9;i++,l=l*10ll+9ll) query(l),e9[i]=get_res(),pw9[i]=l;
        for(int i=9;i>=1;i--) if(!e9[i]) { answer(pw[i]);return 0; }
        answer(pw[0]); return 0;
    }
    int now=8;
    while(!e[now]) now--;
    if(now==0)
    {
        for(ll i=1;i<10;i++)
        {
            query(i*10);
            if(get_res()) { answer(i); return 0; }
        }
    }
    else
    {
        ll k=0;
        for(int i=0;i<now;i++)
        {
            ll l=1,r=9;
            while(l<=r)
            {
                ll mid=l+r>>1;
                query(k*10+mid);
                if(get_res()) l=mid+1;
                else r=mid-1;
            }l--;
            k=k*10+l;
        }
        k*=10ll;
        for(ll i=0;i<10;i++)
        {
            query((k+i)*10);
            if(get_res()) { answer(k+i); return 0; }
        }
    }

    return 0;
}

F
发现最终图会是一条链,链上的边都是桥,链上每个点挂着若干个联通块
用f[i][j]表示当前的集合为i,链的末端是j,保留的边集权值和的最大值
每次转移在末尾加上新的点l或者枚举一个与i不相交的集合k挂在j上面(其实不一定和j相连,只是把它放在j那一块,只保留l∪j集合内的边)

code:

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1e9
using namespace std;

inline void up(int &x,const int &y){if(x<y)x=y;}
const int maxn = 20;
const int maxm = 81000;

int n,m;
int a[maxn][maxn];
int ct[maxm],f[maxm][maxn];

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int x,y,c; scanf("%d%d%d",&x,&y,&c);
        a[x][y]=a[y][x]=c;
    }
    int al=1<<n;
    for(int i=1;i<al;i++)
    {
        int j=1;for(;j<=n;j++) if(i>>j-1&1)break;
        ct[i]=ct[i^1<<j-1];
        for(int k=1;k<=n;k++) if(i>>k-1&1) ct[i]+=a[k][j];
    }
    for(int i=0;i<al;i++) for(int j=1;j<=n;j++) f[i][j]=-inf;

    f[1][1]=0; int re=0;
    for(int i=1;i<al;i+=2)
    {
        for(int j=1;j<=n;j++) if((i>>j-1&1)&&f[i][j]>=0)
        {
            if(j==n) up(re,f[i][j]);
            for(int k=1;k<=n;k++) if(!(i>>k-1&1)&&a[j][k])
                up(f[i|1<<k-1][k],f[i][j]+a[j][k]);

            int now=al-1-i;
            for(int k=now;k;k=k-1&now)
                up(f[i|k][j],f[i][j]+ct[k^1<<j-1]);
        }
    }
    printf("%d\n",ct[al-1]-re);

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值