2017北京国庆刷题Day5 afternoon
期望得分:100+60+100=260
实际得分:0+60+40=100
设图中有m个环,每个环有si条边,有k条边不在环中
ans= (2^s1 -2)*( 2^s2 -2)* (2^s3 -2)…… *( 2^sm -2)* 2^k
(环上的边只有两种可能形成环)
找环好找,怎么找树?
一种方法是tarjan找出所有的环,总边数-环的边数=树的边数
std用了拓扑排序
考场上忘了树的情况,爆零了。
注意:n个点n条边是环套树森林
#include<cstdio>
#define N 100001
using namespace std;
typedef long long LL;
int to[N],d[N],q[N],sum;
const int mod=1e9+;
LL pow(LL a,int b)
{
LL res=;
for(;b;b>>=,a=a*a%mod)
if(b&) res=res*a%mod;
return res;
}
void dfs(int x)
{
sum++;
d[x]=;
if(d[to[x]]) dfs(to[x]);
}
int main()
{
freopen("road.in","r",stdin);
freopen("road.out","w",stdout);
int n;
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&to[i]),d[to[i]]++;
int h=,t=;
for(int i=;i<=n;i++)
if(!d[i]) q[++t]=i;
while(h<=t)
{
if(!(--d[to[q[h]]])) q[++t]=to[q[h]];
++h;
}
LL ans=pow(,t);
for(int i=;i<=n;i++)
if(d[i])
{
sum=;
dfs(i);
ans=ans*(pow(,sum)-)%mod;
}
printf("%I64d",ans);
}
本题60分是经典的n^2 LCS问题
第一个串长1000,第二个串长1e6
很显然枚举只能枚举第一个串
n^2 中是dp[i][j] 表示第一个字符串的前i个字符 与 第二个字符串的前j个字符 的 最长公共子串长度
它的优化是:
dp[i][j] 表示 第一个字符串的前i个字符,与 第二个字符串匹配了长为j的最长公共子串,第j个字符在第二个字符串中的最左下标
这样最后倒序枚举 j,当dp[len1][j]<=len2 时,输出j,return 0
如何转移?
考虑顺推
第一个字符串的第i+1 位如果不发生匹配,那么dp[i+1][j]=min(dp[i+1][j],dp[i][j])
第i+1位如果发生匹配,那么dp[i+1][j+1]=min(dp[i+1][j+1],nxt[dp[i][j]+1][s1[i+1]])
其中nxt[i][j]表示在第二个字符串中,第i位及后面最早出现字符j的位置
#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; #define N 1001
#define M 1000001 char s1[N],s2[M];
int nxt[M][],dp[N+][N]; int main()
{
freopen("lcs.in","r",stdin);
freopen("lcs.out","w",stdout);
scanf("%s%s",s1+,s2+);
int len1=strlen(s1+),len2=strlen(s2+);
for(int i=;i<;i++) nxt[len2+][i]=len2+;
for(int i=len2;i>=;i--)
for(int j=;j<;j++)
if(s2[i]-'a'==j) nxt[i][j]=i;
else nxt[i][j]=nxt[i+][j];
memset(dp,,sizeof(dp));
for(int i=;i<=len1;i++) dp[i][]=;
for(int i=;i<len1;i++)
for(int j=;j<=i && dp[i][j]<=len2;j++)
{
dp[i+][j]=min(dp[i+][j],dp[i][j]);
if(j<len1) dp[i+][j+]=min(dp[i+][j+],nxt[dp[i][j]+][s1[i+]-'a']);
}
for(int i=len1;i>=;i--)
if(dp[len1][i]<=len2) { printf("%d\n",i); return ; }
}
60分暴力:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 1001
using namespace std;
char s1[N],s2[N];
int l1,l2;
int dp[N][N];
int main()
{
freopen("lcs.in","r",stdin);
freopen("lcs.out","w",stdout);
scanf("%s%s",s1+,s2+);
l1=strlen(s1+); l2=strlen(s2+);
for(int i=;i<=l1;i++)
for(int j=;j<=l2;j++)
if(s1[i]==s2[j]) dp[i][j]=dp[i-][j-]+;
else dp[i][j]=max(dp[i-][j],dp[i][j-]);
printf("%d",dp[l1][l2]);
}
题面修改:后面的DEF分别改为CBA
首先很关键的一点:
因为要求操作字典序最小,所以DEF没有用
例如:下面转90相当于上面转270
然后 大模拟
考场上复制时漏改一个数组,丢了60分o(╥﹏╥)o
#include<cstdio>
#include<algorithm>
using namespace std;
int n,tmp[];
int ans[];
int L[][],R[][],U[][],D[][],F[][],B[][];
bool ok;
bool judge(int sum)
{
if(!(L[][]==L[][] && L[][]==L[][] && L[][]==L[][])) return false;
if(!(R[][]==R[][] && R[][]==R[][] && R[][]==R[][])) return false;
if(!(U[][]==U[][] && U[][]==U[][] && U[][]==U[][])) return false;
if(!(D[][]==D[][] && D[][]==D[][] && D[][]==D[][])) return false;
if(!(F[][]==F[][] && F[][]==F[][] && F[][]==F[][])) return false;
if(!(B[][]==B[][] && B[][]==B[][] && B[][]==B[][])) return false;
for(int i=;i<=sum;i++) ans[i]=tmp[i];
ans[]=sum;
return true;
}
void self90(int k[][],int a1,int a2,int b1,int b2,int c1,int c2,int d1,int d2)
{
int t=k[a1][a2];
k[a1][a2]=k[b1][b2]; k[b1][b2]=k[c1][c2]; k[c1][c2]=k[d1][d2]; k[d1][d2]=t;
}
void other90(int k1[][],int a1,int a2,int k2[][],int b1,int b2,int k3[][],int c1,int c2,int k4[][],int d1,int d2)
{
int t=k1[a1][a2];
k1[a1][a2]=k2[b1][b2]; k2[b1][b2]=k3[c1][c2]; k3[c1][c2]=k4[d1][d2]; k4[d1][d2]=t;
a2^=; b2^=; c2^=; d2^=;
t=k1[a1][a2];
k1[a1][a2]=k2[b1][b2]; k2[b1][b2]=k3[c1][c2]; k3[c1][c2]=k4[d1][d2]; k4[d1][d2]=t;
}
void other90_(int k1[][],int a1,int a2,int k2[][],int b1,int b2,int k3[][],int c1,int c2,int k4[][],int d1,int d2)
{
int t=k1[a1][a2];
k1[a1][a2]=k2[b1][b2]; k2[b1][b2]=k3[c1][c2]; k3[c1][c2]=k4[d1][d2]; k4[d1][d2]=t;
a1^=; b1^=; c1^=; d1^=;
t=k1[a1][a2];
k1[a1][a2]=k2[b1][b2]; k2[b1][b2]=k3[c1][c2]; k3[c1][c2]=k4[d1][d2]; k4[d1][d2]=t;
}
void other90_3(int k1[][],int a1,int a2,int k2[][],int b1,int b2,int k3[][],int c1,int c2,int k4[][],int d1,int d2)
{
int t=k1[a1][a2];
k1[a1][a2]=k2[b1][b2]; k2[b1][b2]=k3[c1][c2]; k3[c1][c2]=k4[d1][d2]; k4[d1][d2]=t;
}
void self180(int k[][],int a1,int a2,int b1,int b2,int c1,int c2,int d1,int d2)
{
swap(k[a1][a2],k[b1][b2]);
swap(k[c1][c2],k[d1][d2]);
}
void other180(int k1[][],int a1,int a2,int k2[][],int b1,int b2,int k3[][],int c1,int c2,int k4[][],int d1,int d2)
{
swap(k1[a1][a2],k2[b1][b2]);
swap(k3[c1][c2],k4[d1][d2]);
a2^=; b2^=; c2^=; d2^=;
swap(k1[a1][a2],k2[b1][b2]);
swap(k3[c1][c2],k4[d1][d2]);
}
void other180_(int k1[][],int a1,int a2,int k2[][],int b1,int b2,int k3[][],int c1,int c2,int k4[][],int d1,int d2)
{
swap(k1[a1][a2],k2[b1][b2]);
swap(k3[c1][c2],k4[d1][d2]);
a1^=; b1^=; c1^=; d1^=;
swap(k1[a1][a2],k2[b1][b2]);
swap(k3[c1][c2],k4[d1][d2]);
}
void other180_3(int k1[][],int a1,int a2,int k2[][],int b1,int b2,int k3[][],int c1,int c2,int k4[][],int d1,int d2)
{
swap(k1[a1][a2],k2[b1][b2]);
swap(k3[c1][c2],k4[d1][d2]);
}
void dfs(int x,char ty)
{
if(ok) return;
if(judge(x-)) { ok=true; return; }
if(x==n+) return;
if(ty!='A')
{
self90(U,,,,,,,,);
other90(F,,,R,,,B,,,L,,);
tmp[x]=; dfs(x+,'A');
if(ok) return;
self90(U,,,,,,,,);
other90(F,,,L,,,B,,,R,,); self180(U,,,,,,,,);
other180(F,,,B,,,R,,,L,,);
tmp[x]=; dfs(x+,'A');
if(ok) return;
self180(U,,,,,,,,);
other180(F,,,B,,,R,,,L,,); self90(U,,,,,,,,);
other90(F,,,L,,,B,,,R,,);
tmp[x]=; dfs(x+,'A');
self90(U,,,,,,,,);
other90(F,,,R,,,B,,,L,,);
if(ok) return; }
if(ty!='B')
{
self90(L,,,,,,,,);
other90_(F,,,U,,,B,,,D,,);
tmp[x]=; dfs(x+,'B');
if(ok) return;
self90(L,,,,,,,,);
other90_(F,,,D,,,B,,,U,,); self180(L,,,,,,,,);
other180_(F,,,B,,,U,,,D,,);
tmp[x]=; dfs(x+,'B');
if(ok) return;
self180(L,,,,,,,,);
other180_(F,,,B,,,U,,,D,,); self90(L,,,,,,,,);
other90_(F,,,D,,,B,,,U,,);
tmp[x]=; dfs(x+,'B');
if(ok) return;
self90(L,,,,,,,,);
other90_(F,,,U,,,B,,,D,,);
}
if(ty!='C')
{
self90(F,,,,,,,,);
other90_3(R,,,U,,,L,,,D,,);
other90_3(R,,,U,,,L,,,D,,);
tmp[x]=; dfs(x+,'C');
if(ok) return;
self90(F,,,,,,,,);
other90_3(R,,,D,,,L,,,U,,);
other90_3(R,,,D,,,L,,,U,,); self180(F,,,,,,,,);
other180_3(R,,,L,,,U,,,D,,);
other180_3(R,,,L,,,U,,,D,,);
tmp[x]=; dfs(x+,'C');
if(ok) return;
self180(F,,,,,,,,);
other180_3(R,,,L,,,U,,,D,,);
other180_3(R,,,L,,,U,,,D,,); self90(F,,,,,,,,);
other90_3(R,,,D,,,L,,,U,,);
other90_3(R,,,D,,,L,,,U,,);
tmp[x]=; dfs(x+,'C');
if(ok) return;
self90(F,,,,,,,,);
other90_3(R,,,U,,,L,,,D,,);
other90_3(R,,,U,,,L,,,D,,);
}
}
int main()
{
freopen("cube.in","r",stdin);
freopen("cube.out","w",stdout);
scanf("%d",&n);
scanf("%d%d%d%d",&U[][],&U[][],&U[][],&U[][]);
scanf("%d%d%d%d",&F[][],&F[][],&F[][],&F[][]);
scanf("%d%d%d%d",&L[][],&L[][],&L[][],&L[][]);
scanf("%d%d%d%d",&R[][],&R[][],&R[][],&R[][]);
scanf("%d%d%d%d",&D[][],&D[][],&D[][],&D[][]);
scanf("%d%d%d%d",&B[][],&B[][],&B[][],&B[][]);
dfs(,'G');
for(int i=;i<=ans[];i++) printf("%d ",ans[i]);
return ;
}
2017北京国庆刷题Day5 afternoon的更多相关文章
- 2017北京国庆刷题Day1 afternoon
期望得分:100+100+100=300 实际得分:100+100+100=300 T1 一道图论好题(graph) Time Limit:1000ms Memory Limit:128MB 题目 ...
- 2017北京国庆刷题Day2 afternoon
期望得分:100+100+50=250 实际得分:100+70+50=220 T1 最大值(max) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK有一 ...
- 2017北京国庆刷题Day5 morning
期望得分:0+60+60=120 实际得分:0+30+60=90 令g=gcd(X11,X12,X13……) 则行列式可能为D的充要条件为g|D 1.g|D为必要条件: 由定义来算行列式的时候,每一项 ...
- 2017北京国庆刷题Day4 afternoon
期望得分:100+100+0=200 实际得分:5+0+0=5 每加入一个数,x的因数位置++ 注意:根号x枚举时,如果x是完全平方数,根号x会重复累计2次,要减去 考场上没减,5分 /(ㄒoㄒ)/~ ...
- 2017北京国庆刷题Day6 afternoon
期望得分:100+100+40=240 实际得分:100+0+40=140 二进制拆分.二进制前缀和 #include<cstdio> #include<iostream> u ...
- 2017北京国庆刷题Day3 afternoon
期望得分:100+0+30=130 实际得分:100+36.5+0=136.5 T3 一个变量写混了,丢了30.. 模拟栈 #include<cstdio> #include<cst ...
- 2017北京国庆刷题Day7 afternoon
期望得分:100+30+100=230 实际得分:60+30+100=190 排序去重 固定右端点,左端点单调不减 考场上用了二分,没去重,60 #include<cstdio> #inc ...
- 2017北京国庆刷题Day7 morning
期望得分:100+0+100=200 实际得分:100+20+0=120 离散化搞搞 #include<cstdio> #include<iostream> #include& ...
- 2017北京国庆刷题Day3 morning
期望得分:100+60+0=160 实际得分:100+30+0=130 考场上用的哈希 #include<cstdio> #include<cstring> #include& ...
随机推荐
- Scrum立会报告+燃尽图(十月二十三日总第十四次)
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2246 项目地址:https://git.coding.net/zhang ...
- DL开源框架Caffe | 模型微调 (finetune)的场景、问题、技巧以及解决方案
转自:http://blog.csdn.net/u010402786/article/details/70141261 前言 什么是模型的微调? 使用别人训练好的网络模型进行训练,前提是必须和别人 ...
- lintcode-394-硬币排成线
394-硬币排成线 有 n 个硬币排成一条线.两个参赛者轮流从右边依次拿走 1 或 2 个硬币,直到没有硬币为止.拿到最后一枚硬币的人获胜. 请判定 第一个玩家 是输还是赢? 样例 n = 1, 返回 ...
- shell 一些符号的使用
给你个全的,你在Linux环境下多试下就明白了:$0 这个程式的执行名字$n 这个程式的第n个参数值,n=1..9$* 这个程式的所有参数,此选项参数可超过9个.$# 这个程式的参数个数$$ 这个程式 ...
- 【前端学习笔记】JavaScript JSON对象相关操作
//JSON方法 //JSON.parse(); var json = '{"name":"zj","age":23}'; JSON.par ...
- BZOJ 1567 Blue Mary的战役地图(二维hash+二分)
题意: 求两个矩形最大公共子正方形.(n<=50) 范围这么小可以枚举子正方形的边长.那么可以对这个矩形进行二维hash,就可以在O(1)的时候求出任意子矩形的hash值.然后判断这些正方形的h ...
- jsp和js中获取项目路径名
一.jspa.<%=request.getContextPath()%>//结果:/projectNameb.${pageContext.request.contextPath}//结果: ...
- 【bzoj3295】[Cqoi2011]动态逆序对 树套树 线段树套替罪羊树
这个东西,关于某个数的逆序对数为在他之前比他大的在他之后比他小的数的数目的和,所以删除之前先把这个减去就好了 人傻自带超大常数,中间由于内存池开小了所以运行错误. #include<cstdio ...
- SCWS中文分词,向xdb词库添加新词
SCWS是个不错的中文分词解决方案,词库也是hightman个人制作,总不免有些不尽如人意的地方.有些词语可能不会及时被收入词库中. 幸好SCWS提供了词库XDB导出导入词库的工具(phptool_f ...
- Kerberos的白银票据详解
0x01白银票据(Silver Tickets)定义 白银票据(Silver Tickets)是伪造Kerberos票证授予服务(TGS)的票也称为服务票据.如下图所示,与域控制器没有AS-REQ 和 ...