22/7/11

本文介绍了多种算法的应用,包括ANDSorting寻找最大有序排列,使用Floyd算法求解牛的旅行中直径问题,利用线段树解决滑动窗口最大子数组和,通过传递闭包判断排序可行性,以及DFS搜索括号组合获得最大乘积。这些题目覆盖了排序、图论和数据结构等多个方面。
摘要由CSDN通过智能技术生成

1,cf AND Sorting(思维);2,acwing 1125.牛的旅行(floyed);3,滑动窗口(线段树版);4,acwing 343排序(传递闭包);5,乘积最大(dfs);


1,AND Sorting

题意:给你0~n-1的排列p(不是有序的!!),操作是pi&pj=X,可以交换pi和pj,操作后使得p有序,问X最大?

思路:pi!=i的位置肯定都要交换,所以要&一下,很明显所以不等i的位置&起来就是答案;

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rep1(i,a,n) for(register int i=(a);i<(n);++i) 
#define rep2(i,a,n) for(register int i=(a);i<=(n);++i) 
#define per1(i,n,a) for(register int i=(n);i>(a);i--) 
#define per2(i,n,a) for(register int i=(n);i>=(a);i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pro_q priority_queue
#define pb push_back
#define pf push_front
#define endl "\n"
#define lowbit(m) ((-m)&(m))
#define YES cout<<"YES\n"
#define NO cout<<"NO\n"
#define Yes cout<<"Yes\n"
#define No cout<<"No\n"
#define yes cout<<"yes\n"
#define no cout<<"no\n"
#define yi first
#define er second
#define INF 0x3f3f3f3f
#define tulun int e[N],ne[N],h[N],w[N],idx;
#define add2(a,b) e[idx]=b,ne[idx]=h[a],h[a]=idx++;
#define add3(a,b,c) w[idx]=c,e[idx]=b,ne[idx]=h[a],h[a]=idx++;
#define T_solve() int T;cin>>T;while(T--)solve();
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef double dob;
int n,m;
const int N=1e6+10;
int a[N];   
void solve()
{
    int ans=INT_MAX;
    cin>>n;
    rep1(i,0,n)
    {
        cin>>a[i];
        if(a[i]!=i)ans&=a[i];
    }
    cout<<ans<<endl;
}
signed main()
{
    quick_cin();
    T_solve();
    return 0;
}

2,牛的旅行;

思路:暴力枚举每个可能的点对,求出答案;floyed求出任意两点的最短距离;

 俩个答案取max,因为是直径;

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rep1(i,a,n) for(register int i=(a);i<(n);++i) 
#define rep2(i,a,n) for(register int i=(a);i<=(n);++i) 
#define per1(i,n,a) for(register int i=(n);i>(a);i--) 
#define per2(i,n,a) for(register int i=(n);i>=(a);i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pro_q priority_queue
#define pb push_back
#define pf push_front
#define endl "\n"
#define lowbit(m) ((-m)&(m))
#define YES cout<<"YES\n"
#define NO cout<<"NO\n"
#define Yes cout<<"Yes\n"
#define No cout<<"No\n"
#define yes cout<<"yes\n"
#define no cout<<"no\n"
#define yi first
#define er second
#define INF 0x3f3f3f3f
#define tulun int e[N],ne[N],h[N],w[N],idx;
#define add2(a,b) e[idx]=b,ne[idx]=h[a],h[a]=idx++;
#define add3(a,b,c) w[idx]=c,e[idx]=b,ne[idx]=h[a],h[a]=idx++;
#define T_solve() int T;cin>>T;while(T--)solve();
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef double dob;
const int N=200;
struct node
{
    int x,y;
}a[N];
dob dist[N][N],Maxd[N],ans1,ans2=INF;
int n,m,maps[N][N];
char c;
void floyed()
{
    rep2(k,1,n)
    rep2(i,1,n)
    rep2(j,1,n)
    dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
    
}
double len(int x1,int y1,int x2,int y2)
{
    return sqrt(pow(x1-x2,2)+pow(y1-y2,2));
}
signed main()
{
    quick_cin();
    cin>>n;
    rep2(i,1,n)
    {
        cin>>a[i].x>>a[i].y;
    }
    rep2(i,1,n)
    rep2(j,1,n)
    {
        cin>>c;
        maps[i][j]=c-'0';
    }
    rep2(i,1,n)
    rep2(j,1,n)
    {
        if(maps[i][j])
        dist[i][j]=len(a[i].x,a[i].y,a[j].x,a[j].y);
        else if(i!=j)
        {
            dist[i][j]=INF;
        }
    }
    floyed();
    rep2(i,1,n)
    rep2(j,1,n)
    {
        if(dist[i][j]!=INF)
        {
            Maxd[i]=max(dist[i][j],Maxd[i]);
        }
        ans1=max(ans1,Maxd[i]);
    }
    rep2(i,1,n)
    rep2(j,1,n)
    {
        if(dist[i][j]==INF)
        {
            ans2=min(Maxd[i]+len(a[i].x,a[i].y,a[j].x,a[j].y)+Maxd[j],ans2);
        }
    }
    dob ans=max(ans1,ans2);
    cout<<fixed<<setprecision(6)<<ans;
    return 0;
}

3,滑动窗口;

 之前用单调队列写过,这次用线段树实现;顺便复习1个多月没写过的线段树;

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rep1(i,a,n) for(register int i=(a);i<(n);++i) 
#define rep2(i,a,n) for(register int i=(a);i<=(n);++i) 
#define per1(i,n,a) for(register int i=(n);i>(a);i--) 
#define per2(i,n,a) for(register int i=(n);i>=(a);i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pro_q priority_queue
#define pb push_back
#define pf push_front
#define endl "\n"
#define lowbit(m) ((-m)&(m))
#define YES cout<<"YES\n"
#define NO cout<<"NO\n"
#define Yes cout<<"Yes\n"
#define No cout<<"No\n"
#define yes cout<<"yes\n"
#define no cout<<"no\n"
#define yi first
#define er second
#define INF 0x3f3f3f3f
#define tulun int e[N],ne[N],h[N],w[N],idx;
#define add2(a,b) e[idx]=b,ne[idx]=h[a],h[a]=idx++;
#define add3(a,b,c) w[idx]=c,e[idx]=b,ne[idx]=h[a],h[a]=idx++;
#define T_solve() int T;cin>>T;while(T--)solve();
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef double dob;
const int N=1e6+10;
struct node
{
    int l,r;
    int v;
    int maxv,minv;
}tr[N<<2];
int n,k;
int w[N];
void pushup(int u)
{
    tr[u].maxv=max(tr[u<<1].maxv,tr[u<<1|1].maxv);
    tr[u].minv=min(tr[u<<1].minv,tr[u<<1|1].minv);
}
void bulid(int u,int l,int r)
{
    tr[u]={l,r};
    if(l==r)
    {
        tr[u].v=tr[u].maxv=tr[u].minv=w[l];
        return ;
    }
    int mid=l+r>>1;
    bulid(u<<1,l,mid),bulid(u<<1|1,mid+1,r);
    pushup(u);
}
PII query(int u,int l,int r)
{
    if(tr[u].l>=l&&tr[u].r<=r)return {tr[u].maxv,tr[u].minv};
    else
    {
        int mid=tr[u].l+tr[u].r>>1;
        int maxxv=INT_MIN,minnv=INT_MAX;
        if(l<=mid)
        {
            PII x=query(u<<1,l,r);
            maxxv=max(maxxv,x.first);
            minnv=min(minnv,x.second);
        }
        if(r>mid)
        {
            PII x=query(u<<1|1,l,r);
            maxxv=max(maxxv,x.first);
            minnv=min(minnv,x.second);
        }
        return {maxxv,minnv};
    }

}
vector<PII>ans;
signed main()
{
    quick_cin();
    cin>>n>>k;
    rep2(i,1,n)cin>>w[i];
    bulid(1,1,n);
    rep2(i,k,n)
    {
        ans.pb(query(1,i-k+1,i));
    }
    int siz=ans.size();
    rep1(i,0,siz)cout<<ans[i].second<<" "; 
    cout<<endl;
    rep1(i,0,siz)cout<<ans[i].first<<" ";
    return 0;
}

4,排序;

思路:先判断有无矛盾 ,在确定输出次序;

用到了floyed算法的另一个用途,判断两个点之间是否通达;

如果到达自身了,那说明a<b<a传回来了,有矛盾;

如果j无法到i且i无法到j,则无法确定;

剩下的就是符合顺序; 

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rep1(i,a,n) for(register int i=(a);i<(n);++i) 
#define rep2(i,a,n) for(register int i=(a);i<=(n);++i) 
#define per1(i,n,a) for(register int i=(n);i>(a);i--) 
#define per2(i,n,a) for(register int i=(n);i>=(a);i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pro_q priority_queue
#define pb push_back
#define pf push_front
#define endl "\n"
#define lowbit(m) ((-m)&(m))
#define YES cout<<"YES\n"
#define NO cout<<"NO\n"
#define Yes cout<<"Yes\n"
#define No cout<<"No\n"
#define yes cout<<"yes\n"
#define no cout<<"no\n"
#define yi first
#define er second
#define INF 0x3f3f3f3f
#define tulun int e[N],ne[N],h[N],w[N],idx;
#define add2(a,b) e[idx]=b,ne[idx]=h[a],h[a]=idx++;
#define add3(a,b,c) w[idx]=c,e[idx]=b,ne[idx]=h[a],h[a]=idx++;
#define T_solve() int T;cin>>T;while(T--)solve();
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef double dob;
const int N=26;
int n,m;
bool g[N][N],d[N][N];
bool st[N];
void floyed()
{
    memcpy(d,g,d);
    rep1(k,0,n)
    rep1(i,0,n)
    rep1(j,0,n)
    d[i][j]|=d[i][k]&&d[k][j];
}
int check()
{
    rep1(i,0,n)
    if(d[i][i])return 2;
    rep1(i,0,n)
        rep1(j,0,i)if(!d[i][j]&&!d[j][i])
                   return 0;
    return 1;
}
char get_min()
{
    rep1(i,0,n)
    {
        if(!st[i])
        {
            bool flag=1;
            rep1(j,0,n)
            {
                if(!st[j]&&d[j][i])
                {
                    flag=0;
                    break;
                }
            }
            if(flag)
            {
                st[i]=1;
                return 'A'+i;
            }
        }
    }
}
signed main()
{
    quick_cin();
    while(cin>>n>>m,n||m)
    {
        memset(g,0,g);
        int type=0,t;
        rep2(i,1,m)
        {
            char str[5];
            cin>>str;
            int a=str[0]-'A',b=str[2]-'A';
            if(!type)
            {
                g[a][b]=1;
                floyed();
                type=check();
                if(type)t=i;
            }
        }
        if(!type)cout<<"Sorted sequence cannot be determined.\n";
        else if(type==2)cout<<"Inconsistency found after "<<t<<" relations.\n";
        else
        {
            memset(st,0,st);
            cout<<"Sorted sequence determined after "<<t<<" relations: ";
            rep1(i,0,n)cout<<get_min();
            cout<<".\n";
        }
    }
    return 0;
}

5,乘积最大;

 数据很小,dfs暴搜枚举括号的位置;

注意细节,我是把下标左边的算作一个数,所以实际上枚举到n-1就要return,不能把n-1的位置也枚举,否则stol会抛出错误,因为是个空格;

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rep1(i,a,n) for(register int i=(a);i<(n);++i) 
#define rep2(i,a,n) for(register int i=(a);i<=(n);++i) 
#define per1(i,n,a) for(register int i=(n);i>(a);i--) 
#define per2(i,n,a) for(register int i=(n);i>=(a);i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pro_q priority_queue
#define pb push_back
#define pf push_front
#define endl "\n"
#define lowbit(m) ((-m)&(m))
#define YES cout<<"YES\n"
#define NO cout<<"NO\n"
#define Yes cout<<"Yes\n"
#define No cout<<"No\n"
#define yes cout<<"yes\n"
#define no cout<<"no\n"
#define yi first
#define er second
#define INF 0x3f3f3f3f
#define tulun int e[N],ne[N],h[N],w[N],idx;
#define add2(a,b) e[idx]=b,ne[idx]=h[a],h[a]=idx++;
#define add3(a,b,c) w[idx]=c,e[idx]=b,ne[idx]=h[a],h[a]=idx++;
#define T_solve() int T;cin>>T;while(T--)solve();
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef double dob;
const int N=1e3+10;
int n,k;
LL ans;
string s;
vector<int>xl;
void dfs(int u,int cnt)
{
    if(cnt==k)
    {
        LL mul=1;
        LL num;
        if(xl.size()!=k)
        {
            cout<<"no";
            return;
        }
        rep1(i,0,k)
        {
            if(i==0)
            {
                num=stol(s.substr(0,xl[0]+1));
            }
            else
            {
                num=stol(s.substr(xl[i-1]+1,xl[i]-xl[i-1]));
            }
            mul*=num;
        }
        num=stol(s.substr(xl[k-1]+1,n-1-xl[k-1]));
         //cout<<"jb: "<<(s.substr(xl[k-1]+1,n-1-xl[k-1]))<<" l: "<<xl[k-1]<<endl;
        mul*=num;
        ans=max(ans,mul);
        return;
    }
    if(u>=n-1)return;
    xl.pb(u);
    dfs(u+1,cnt+1);
    xl.pop_back();
    dfs(u+1,cnt);
}
signed main()
{
    //quick_cin();
    cin>>n>>k;
    cin>>s;
    dfs(0,0);
    cout<<ans;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dull丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值