当前位置: 首页 > news >正文

[NowCoder]牛客OI周赛3

A.地斗主

题意:\(4\times N\) 的地板,在上面铺 \(1\times 2\)\(2\times 1\) 的地砖,求铺满方案数, \(N\le 10^9\)

原题。。先把一列的状态压缩成二进制,这一格为1就表示这一格被左边一列横着占用了

为0表示没被左边占用(放了竖着的或者没放都是一样的)

可以推出一系列转移,最后发现有用状态只有6个,有两个方案数总是一样,可以合并

因此用矩阵乘法加速递推即可

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i(a);i<=(b);++i)
using namespace std;
typedef long long ll;
inline int read(){char c,p=0;int w;
    while(isspace(c=getchar()));if(c=='-')p=1,c=getchar();
    for(w=c&15;isdigit(c=getchar());w=w*10+(c&15));return p?-w:w;
}
int n,m;
struct mat{
    int v[5][5];
    mat(){memset(v,0,sizeof v);}
    inline int*operator[](const int&i){return v[i];}
    inline mat operator*(mat&r){
        mat ans;REP(k,0,4)REP(i,0,4)REP(j,0,4)
        ans[i][j]=(ans[i][j]+1ll*v[i][k]*r[k][j])%m;
        return ans;
    }
}A,B,C;
inline mat fpow(mat x,int k){
    mat r;REP(i,0,4)r[i][i]=1;
    for(;k;k>>=1,x=x*x)if(k&1)r=r*x;return r;
}
int main(){
    A[0][0]=A[0][1]=A[0][4]=1;A[0][2]=2;
    A[1][0]=A[2][0]=1,A[2][2]=1,A[3][4]=1,
    A[4][0]=A[4][3]=1;
    B[0][0]=1;
    int T=read();
    while(T--){
        n=read(),m=read();
        C=fpow(A,n)*B;
        io.print(C[0][0]);
    }
    return 0;
}

B.1048

题意:\(N\) 个白球和 \(N\) 个黑球,每个都以 \(1\dots N\) 标号,现在给出每个球的颜色和标号,要求用最少的步数邻项交换,使得白球是有序的,黑球也是有序的,\(N\le 2000\)

由邻项交换可以想到冒泡排序,冒泡排序的最小交换次数是逆序对,考虑DP

\(f[i][j]\) 表示 已经排了前 \(i\) 个白球,前 \(j\) 个黑球(都在最前面)的最小代价。

若用 \(i\) 转移,则代价是 在 \(i\) 前面,比 \(i\) 大的白球数目 和 在 \(i\) 前面, 比 \(j\) 大的黑球数目,简单起见用 \(c1[i]\) 表示;同理,若用 \(j\) 转移,代价是 \(c2[j]\)
\[ f[i][j]=min(f[i-1][j]+c1[i],f[i][j-1]+c2[j]) \]

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i(a);i<=(b);++i)
#define dbg(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
template<typename T,typename U>inline char smin(T&x,const U&y){return x>y?x=y,1:0;}
template<typename T,typename U>inline char smax(T&x,const U&y){return x<y?x=y,1:0;}
const int N=2005;
int n,f[N][N],p[2][N],cnt[2][N<<1][N];
int main(){
    scanf("%d",&n);
    REP(i,1,n<<1){
        char c;int x;scanf("%s%d",&c,&x);
        p[c=='B'][x]=i;
        REP(j,i,n<<1)++cnt[c=='B'][j][x];
    }
    REP(k,0,1)REP(i,1,n<<1)for(int j=n;~j;--j)cnt[k][i][j]+=cnt[k][i][j+1];
    REP(i,0,n)REP(j,0,n){
        if(i||j)f[i][j]=1e9;
        if(i)smin(f[i][j],f[i-1][j]+cnt[1][p[0][i]-1][j+1]+cnt[0][p[0][i]-1][i+1]);
        if(j)smin(f[i][j],f[i][j-1]+cnt[0][p[1][j]-1][i+1]+cnt[1][p[1][j]-1][j+1]);
    }
    cout<<f[n][n];
    return 0;
}

C.爆瓶子

题意:你有 \(N\) 种瓶子每种 \(N\) 个,需要把它排成 \(N\times N\) 的方阵,要求每行每列不能有相同瓶子,输出字典序最小的方案 \(N \le 220\)

垃圾题,跟着数据卡数据范围,暴力二分图匹配

一行一行进行二分图匹配,匹配了就把对应的边删掉,得出一组匹配后再看能不能和前面交换得到字典序更小的匹配

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i(a);i<=(b);++i)
using namespace std;
inline int read(){char c,p=0;int w;
    while(isspace(c=getchar()));if(c=='-')p=1,c=getchar();
    for(w=c&15;isdigit(c=getchar());w=w*10+(c&15));return p?-w:w;
}
const int N=225;
int n,m,head[N],pre[N][N],nxt[N][N],vis[N],T,bel[N],to[N];
inline void del(int i,int j){
    if(j==head[i])head[i]=nxt[i][j];
    else pre[i][nxt[i][j]]=pre[i][j],nxt[i][pre[i][j]]=nxt[i][j];
}
inline bool dfs(int x,int lim){
    for(int i=head[x];i;i=nxt[x][i])if(vis[i]!=T){
        vis[i]=T;
        if(!bel[i]||bel[i]>lim&&dfs(bel[i],lim))
        return to[x]=i,bel[i]=x,1;
    }
    return 0;
}
inline void solve(){
    REP(i,1,n)++T,dfs(i,0);
    REP(i,1,n){
        ++T;
        for(int j=head[i];j;j=nxt[i][j]){
            if(bel[j]==i)break;
            if(bel[j]<i)continue;
            int x=bel[j],y=to[i];
            to[i]=j,bel[j]=i,to[x]=bel[y]=0;
            if(dfs(x,i))break;
            to[x]=j,bel[j]=x,to[i]=y,bel[y]=i;
        }
    }
}
int main(){
    int t=read();
    while(t--){
        n=read();m=read();
        REP(i,1,n){
            REP(j,1,n)pre[i][j]=j-1,nxt[i][j]=j+1;nxt[i][n]=0;head[i]=1;
        }
        REP(i,1,m)REP(j,1,n)del(j,read());
        REP(i,m+1,n){
            memset(to,0,sizeof to);
            memset(bel,0,sizeof bel);
            memset(vis,0,sizeof vis);
            T=0,solve();
            REP(j,1,n)del(j,to[j]),printf("%d ",to[j]);puts("");
        }
    }
    return 0;
}

转载于:https://www.cnblogs.com/HolyK/p/9835130.html

相关文章:

  • 如何构建安全的.net web应用系统
  • 安全辅助 Autoruns8.61
  • Python——NumPy的使用
  • 开学了,一切都要开始了!
  • WPF DataGrid分页功能实现代码
  • HTTP应答状态
  • JAVA常用系统类
  • Windows系统常遇***的预防技巧
  • c# 三种计算程序运行时间的方法
  • 0.单向链表的创建
  • ×××计算机信息系统安全保护条例
  • 索引切片步长
  • DataGridView 密码列(显示为*号)的设置
  • Yeslab华为安全HCIE七门之--防火墙高级技术(17篇)
  • 七日瘦身汤
  • 【Leetcode】101. 对称二叉树
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • Apache Pulsar 2.1 重磅发布
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • Java超时控制的实现
  • JS变量作用域
  • mac修复ab及siege安装
  • Web Storage相关
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 关于for循环的简单归纳
  • 看域名解析域名安全对SEO的影响
  • 前端面试之闭包
  • 软件开发学习的5大技巧,你知道吗?
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 小试R空间处理新库sf
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (6)STL算法之转换
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第7章第3节(封装和窗体)
  • (编译到47%失败)to be deleted
  • (独孤九剑)--文件系统
  • (删)Java线程同步实现一:synchronzied和wait()/notify()
  • (转) ns2/nam与nam实现相关的文件
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • (转)关于多人操作数据的处理策略
  • *2 echo、printf、mkdir命令的应用
  • .describe() python_Python-Win32com-Excel
  • .equals()到底是什么意思?
  • .helper勒索病毒的最新威胁:如何恢复您的数据?
  • .NET 3.0 Framework已经被添加到WindowUpdate
  • .NET Core MongoDB数据仓储和工作单元模式封装
  • .Net Remoting常用部署结构
  • .NET上SQLite的连接
  • .Net中wcf服务生成及调用
  • .vue文件怎么使用_我在项目中是这样配置Vue的
  • @param注解什么意思_9000字,通俗易懂的讲解下Java注解
  • @select 怎么写存储过程_你知道select语句和update语句分别是怎么执行的吗?
  • [ IOS ] iOS-控制器View的创建和生命周期