头像

shyyhs


访客:1115

在线 


新鲜事 原文

shyyhs
26天前
还有5个搜索就终于结束搜索了,好难哎QAQ
图片



shyyhs
1个月前

QAQ自闭了



题目讨论 AcWing 178. 有向边

shyyhs
1个月前

建议加下有向边的指向–




shyyhs
1个月前

昨天把数独2按y大佬思路打了1遍,今天又来了一个推箱子QAQ好恶心




shyyhs
1个月前

事实证明数组比set快多了,我set调了很多,最多也就过了9个数据,改成数组直接ac了QAQ

#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
typedef long long ll;
const int N=50;
ll ans=-1,w,n,g=0,t=0;
int a[N],vis[N];
int cnt[1<<24];
int bcnt[1<<24];
set<ll>s;
void dfs1(ll e,int start)
{
    cnt[g++]=e;
    for(int i=start;i<n/2;i++)
    {
        if(e+a[i]>w)   continue;
        else           dfs1(e+a[i],i+1);
    }
}
void dfs2(ll e,int start)
{
   // auto x=s.upper_bound(w-e);x--;
   int pos=upper_bound(bcnt,bcnt+t,w-e)-bcnt-1;
    ans=max(ans,e+bcnt[pos]);
    for(int i=start;i<n;i++)
    {
        if(e+a[i]>w)   continue;
        else           dfs2(e+a[i],i+1);
    }
}

int main()
{
    cin>>w>>n;
    for(int i=0;i<n;i++) scanf("%d",&a[i]);
    sort(a,a+n);
    reverse(a,a+n);
    dfs1(0,0);
    sort(cnt,cnt+g);
    bcnt[0]=cnt[0];
    for(int i=1;i<g;i++)
    {
        while(cnt[i]==bcnt[t]) i++;
        bcnt[t++]=cnt[i];
    }
 //   for(int i=0;i<t;i++) cout<<bcnt[i]<<' ';cout<<endl;
    sort(a+n/2,a+n);
    reverse(a+n/2,a+n);
    dfs2(0,n/2);
    cout<<ans<<endl;
    return 0;
}

就是二分预处理一下,时间复杂度刚好卡过去QAQ




shyyhs
1个月前
#include <bits/stdc++.h>
using namespace std;
const int N=16;
int mp[1<<(N+1)+1],ones[1<<(N+1)+1],state[N+1][N+1],bstate[N*N+1][N+1][N+1],bstate2[N*N+1][N+1][N+1];
char str[N][N+1],bstr[N*N+1][N+1][N+1];
void init()
{
    for(int i=0;i<N;i++)
    {
        for(int j=0;j<N;j++)
        {
            state[i][j]=(1<<N)-1;
        }
    }
}

inline int lowbit(int x)
{
    return x&(-x);
}

void draw(int x,int y,int c)
{
    str[x][y]='A'+c;
    for(int i=0;i<N;i++)
    {
          state[x][i]&=~(1<<c);
          state[i][y]&=~(1<<c);
    }
    int sx=x/4*4,sy=y/4*4;
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            state[sx+i][sy+j]&=~(1<<c);
        }
    }
    state[x][y]=1<<c;   
}

bool dfs(int cnt)
{
    if(!cnt) return true;
    int bcnt=cnt;
    memcpy(bstr[bcnt],str,sizeof str);
    memcpy(bstate[bcnt],state,sizeof state);
    //剪枝1:
    for(int i=0;i<N;i++)
    {
        for(int j=0;j<N;j++)
        {
            if(str[i][j]=='-')
            {
                if(!state[i][j])
                {
                    memcpy(state,bstate[bcnt],sizeof state);
                    memcpy(str,bstr[bcnt],sizeof str);
                    return false;
                }
                if(ones[state[i][j]]==1)
                {
                    draw(i,j,mp[state[i][j]]);
                    cnt--;
                }
            }

        }
    }
    //剪枝2:
    for(int i=0;i<N;i++)//枚举每一行
    {
        int ck=0;int s=0;int sand=(1<<N)-1;
        for(int j=0;j<N;j++)//枚举每一行的每一个数
        {
            sand&=~(state[i][j]&s);//排除多个选择的数
            s|=state[i][j];//看下是否全部覆盖
            if(str[i][j]!='-') ck|=state[i][j];//排除已经填过的数

        }
        if(s!=(1<<N)-1)
        {
             memcpy(state,bstate[bcnt],sizeof state);
             memcpy(str,bstr[bcnt],sizeof str);
             return false;
        }
        for(int j=sand;j;j-=lowbit(j))
        {
            int t=lowbit(j);
            if(!(t&ck))
            {
                for(int k=0;k<N;k++)
                {
                    if (state[i][k]&t)
                    {
                        draw(i,k,mp[t]);
                        cnt--;
                        break;
                    }
                }
            }
        }
    }
    //剪枝3:
    for(int i=0;i<N;i++)//枚举每一列
    {
        int ck=0;int s=0;int sand=(1<<N)-1;
        for(int j=0;j<N;j++)//枚举每一行的每一个数
        {
            sand&=~(state[j][i]&s);//排除多个选择的数
            s|=state[j][i];//看下是否全部覆盖
            if(str[j][i]!='-') ck|=state[j][i];//排除已经填过的数
        }
        if(s!=(1<<N)-1)
        {
             memcpy(state,bstate[bcnt],sizeof state);
             memcpy(str,bstr[bcnt],sizeof str);
             return false;
        }
        for(int j=sand;j;j-=lowbit(j))
        {
            int t=lowbit(j);
            if(!(t&ck))
            {
                for(int k=0;k<N;k++)
                {
                    if (state[k][i]&t)
                    {
                        draw(k,i,mp[t]);
                        cnt--;
                        break;
                    }
                }
            }
        }
    }
    //剪枝4:
    for(int i=0;i<N;i++)//枚举16宫格的编号
    {
        int ck=0;int s=0;int sand=(1<<N)-1;
        for(int j=0;j<N;j++)//枚举在16宫格的每个位子
        {
            int sx=i/4*4,sy=i%4*4;
            int dx=j/4,dy=j%4;
            sand&=~(state[i][j]&s);//排除多个选择的数
            s|=state[sx+dx][sy+dy];//看下是否全部覆盖
            if(str[sx+dx][sy+dy]!='-') ck|=state[sx+dx][sy+dy];//排除已经填过的数
        }
        if(s!=(1<<N)-1)
        {
             memcpy(state,bstate[bcnt],sizeof state);
             memcpy(str,bstr[bcnt],sizeof str);
             return false;
        }
        for(int j=sand;j;j-=lowbit(j))
        {
            int t=lowbit(j);
            if(!(t&ck))
            {
                for(int k=0;k<N;k++)
                {
                    int sx=i/4 *4,sy=i%4*4;
                    int dx=k/4,dy=k%4;
                    if (state[sx+dx][sy+dy]&t)
                    {
                        draw(sx+dx,sy+dy,mp[t]);
                        cnt--;
                        break;
                    }
                }
            }
        }
    }
    //剪枝5:
    int x,y,sum=30;
    for(int i=0;i<N;i++)
    {
        for(int j=0;j<N;j++)
        {
            if(str[i][j]=='-'&&ones[state[i][j]]<sum)
            {
                sum=ones[state[i][j]];
                x=i,y=j;
            }
        }
    }
    memcpy(bstate2[bcnt],state,sizeof state);
    for (int i = state[x][y]; i; i -= lowbit(i))
    {
        memcpy(state,bstate2[bcnt],sizeof state);
        draw(x,y,mp[lowbit(i)]);
        if(dfs(cnt - 1)) return true;
    }
    memcpy(state,bstate[bcnt],sizeof state);
    memcpy(str,bstr[bcnt],sizeof str);
    return false;
}

int main()
{
    for(int i=0;i<N;i++) mp[1<<i]=i;
    for(int i=1;i<1<<N;i++)
    {
        for(int j=i;j;j-=lowbit(j))
        {
            ones[i]++;
        }
    }
    while(cin>>str[0])
    {
        int cnt=0;
        for(int i=1;i<N;i++) cin>>str[i];
        init();
        for(int i=0;i<N;i++)
        {
            for(int j=0;j<N;j++)
            {
                if(str[i][j]!='-')
                {
                    draw(i,j,str[i][j]-'A');                   
                }
                else cnt++;
            }
        }
        dfs(cnt);
        for(int i=0;i<N;i++) cout<<str[i]<<endl;
        cout<<endl;
    }
    return 0;
}


题目讨论 AcWing 169. hh

shyyhs
1个月前

先让我看会番再考虑把这代码写写–QAQ



题目讨论 AcWing 1. 我好菜

shyyhs
1个月前

我好菜,搜索咋就学不会–qwq




shyyhs
1个月前

耐心刷题~耐心刷题!希望早日会做a+b orzz




shyyhs
1个月前

这种字符相同的一般哈希还是好些,毕竟好懂嘛~代码也不长…下面也有注释.这题和那个排序的那个题目基本类似.还是很简单的,第一次在acwing写题解–有点不适应hh

/*
算法:哈希+二分
实现:
for(int i=1;i<=n;i++)//枚举a串的起点.然后二分a串寻找和b串长度最优匹配的,然后cnt一下最长长度
{

}
二分后的长度怎么检测呢?
假定我们已经处理完了h[n],我现在要求l~l+len
*/
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+5;
typedef unsigned long long ull;
int cnt[N],base=131;
ull p[N],h1[N],h2[N];
char s1[N],s2[N];
ull get(int l,int r,ull h[]) { return h[r]-h[l-1]*p[r-l+1]; }
int main()
{
    int n,m,q;
    cin>>n>>m>>q;
    scanf("%s",s1+1);
    scanf("%s",s2+1);
    p[0]=1;
    for(int i=1;i<=n;i++) p[i]=p[i-1]*base;
    for(int i=1;i<=n;i++) { h1[i]=h1[i-1]*base+s1[i]-'a';}
    for(int i=1;i<=m;i++) { h2[i]=h2[i-1]*base+s2[i]-'a';}
    for(int i=1;i<=n;i++)
    {
        int l=0,r=min(n,m),ans=0;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(get(i,i+mid,h1)==get(1,mid+1,h2)) { ans=max(ans,mid)+1; l=mid+1; }
            else               r=mid-1;
        }
        cnt[ans]++;
    }
    int x;
    while(q--)
    {
        cin>>x;
        cout<<cnt[x]<<endl;
    }
    return 0;
}