按题意模拟

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+500;
int w[N];
int main()
{
    int T;
    scanf("%d",&T);
//    T=1;
    while(T--)
    {
        int n;
        scanf("%d",&n);
        string s;
        cin>>s;
        int i;
        for(i=n-1;i>=0;i--)
        {
            if(s[i]!=')') break;
        }
        int h=i+1;
        int q=n-h;
        if(h>=q) cout<<"No"<<endl;
        else cout<<"Yes"<<endl;
    }
    return 0;
}


往后暴力寻找答案,即可.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+500;
int w[N];bool vis[10];
bool ck(ll x)
{
    memset(vis,false,sizeof vis);
    ll num=x;
    while(x)
    {
        vis[x%10]=true;
        x/=10;
    }
    for(int i=1;i<=9;i++)
        if(vis[i])
        {
            if(num%i!=0)    return false;
        }
    return true;

}
int main()
{
    int T;
    scanf("%d",&T);
//    T=1;
    while(T--)
    {
        ll n;
        scanf("%lld",&n);
        while(!ck(n))    n++;
        printf("%lld\n",n);
    }
    return 0;
}


对于一个环来说,它的拆开是需要n+1步的,因为第一步是要拆环,对于不在对角线上也不成环的环每次只需要1步,这里用dsu统计环的数量即可.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+500;
int fa[N],sz[N];
int vis[N];
int dsu(int u)
{
    if(u==fa[u])    return u;
    else            return fa[u]=dsu(fa[u]);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        int ans=0;
        for(int i=1;i<=n;i++)    fa[i]=i,sz[i]=1,vis[i]=0;
        ans=m;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            if(x==y)    
            {
                ans--;continue;    
            }
            if(dsu(x)==dsu(y))    vis[dsu(x)]=1;
            else                sz[dsu(x)]++;
            fa[dsu(y)]=dsu(x);
        }
        for(int i=1;i<=n;i++)
        {
            if(vis[dsu(i)]==1)        ans++,vis[dsu(i)]=2;
        }
        printf("%d\n",ans);
    }
    return 0;
}


贪心即可,我们可以知道$填是连续的,对于每一段来说,我们肯定是在前面一段全填1/0,后面一段全填0/1.

假设我们还有一个更优的解法,那么我肯定是交换某个1/0..这样产生的结果(01/10串的数目)是不变的,所以发现只与0/1的数目有关.如此这种处理即是最好做的,因为它会严格的使得某种01/10偏大.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+500;
char s[N];
ll pre_zero[N],suf_zero[N],pre_one[N],suf_one[N],pre[N],suf[N];
ll ans_pzero[N],ans_fzero[N],ans_pone[N],ans_fone[N];
int main()
{
    scanf("%s",s+1);
    ll x,y;scanf("%lld%lld",&x,&y);
    int n=strlen(s+1);
    for(int i=1;i<=n;i++)
    {
        pre_zero[i]=pre_zero[i-1];
        pre_one[i]=pre_one[i-1];
        pre[i]=pre[i-1];
        if(s[i]=='0')        pre_zero[i]++;
        else if(s[i]=='?')    pre[i]++;
        else                pre_one[i]++;
    }
    for(int i=n;i>=1;i--)
    {
        suf_one[i]=suf_one[i+1];
        suf_zero[i]=suf_zero[i+1];
        suf[i]=suf[i+1];
        if(s[i]=='0')        suf_zero[i]++;
        else if(s[i]=='?')    suf[i]++;
        else                suf_one[i]++;
    }
    //1.前面填0的答案.
    for(int i=1;i<=n;i++)
    {
        ans_pzero[i]=ans_pzero[i-1];
        if(s[i]=='0'||s[i]=='?')
        {
            ans_pzero[i]+=pre_one[i]*y;
        }
        else
        {
            ans_pzero[i]+=(pre_zero[i]+pre[i])*x;
        }
    }
    //2.前面填1的答案.
    for(int i=1;i<=n;i++)
    {
        ans_pone[i]=ans_pone[i-1];
        if(s[i]=='1'||s[i]=='?')
        {
            ans_pone[i]+=pre_zero[i]*x;
        }
        else
        {
            ans_pone[i]+=(pre_one[i]+pre[i])*y;
        }
    }
    //3.后面填0的答案.
    for(int i=n;i>=1;i--)
    {
        ans_fzero[i]=ans_fzero[i+1];
        if(s[i]=='0'||s[i]=='?')
        {
            ans_fzero[i]+=suf_one[i]*x;
        }
        else
        {
            ans_fzero[i]+=(suf_zero[i]+suf[i])*y;
        }
    }
    //4.后面填1的答案. 
    for(int i=n;i>=1;i--)
    {
        ans_fone[i]=ans_fone[i+1];
        if(s[i]=='1'||s[i]=='?')
        {
            ans_fone[i]+=suf_zero[i]*y;
        }
        else
        {
            ans_fone[i]+=(suf_one[i]+suf[i])*x;
        }
    }
    //5.统计答案.
    ll ans=2e18;
    for(int i=0;i<=n;i++)
    {
        ans=min(ans,ans_pzero[i]+ans_fone[i+1]+(pre_zero[i]+pre[i])*(suf_one[i+1]+suf[i+1])*x+(pre_one[i])*(suf_zero[i+1])*y);
        ans=min(ans,ans_pone[i]+ans_fzero[i+1]+(pre_one[i]+pre[i])*(suf_zero[i+1]+suf[i+1])*y+(pre_zero[i])*(suf_one[i+1])*x);
    }printf("%lld\n",ans);
    return 0;
}


对于这题来说,我们手画一下可以发现:当n>=2时,n项为正,n-1项为负,其他可以任意符号.如此我们可以二进制贪心填充即可.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+500;
int num[30];
char s[N];
int main()
{
    ll n,T;
    scanf("%lld%lld",&n,&T);
    scanf("%s",s+1);
    for(int i=1;i<=n-2;i++)
    {
        num[s[i]-'a']++;
    }
    //第n个符号是正,n-1个符号是负. 
    ll now=(1ll<<(s[n]-'a'))-(1ll<<(s[n-1]-'a'));
    T-=now;
    for(ll i=25;i>=0;i--)
    {
        while(T>0&&num[i])    T-=(1ll<<i),num[i]--;
    }
    for(ll i=25;i>=0;i--)
    {
        while(T<=-(1ll<<i)&&num[i])    T+=(1ll<<i),num[i]--;
    }
    if(T)    { puts("NO"); return 0;}
    bool ans=false;
    now=0;
    //剩下的数凑完即可.
    for(ll i=25;i>=0;i--)
    {
        if((num[i]&1)&&now==0)    now+=(1ll<<i);
        else if(now!=0)
        {
            while(now>=(1ll<<i)&&num[i])    now-=(1ll<<i),num[i]--;
            if(num[i]&1)    now+=(1ll<<i);
        }
    }
    if(!now)    ans=true;
    if(ans)    puts("YES");
    else    puts("NO");
    return 0;
}
/*
4 7
adaa
*/


待补.