2017/11/1模拟赛

磁星(magnet
【题目描述】
在 B 城呆惯了的小 H 决定去外太空溜达一圈。
人类现已发现并开发的星球(包括小 H 所在的星球)有 n 个,
并且在这 n 个星球之中,人们发现了 m 对两个星球的关系。关系“x
y”表示的是星球 x 对星球 y 有 1 一个单位的引导力,由于引导力还
具有传递性,如果星球 x 对星球 y 能有恰好 a 个单位的引导力,星球
y 对星球 z 能有恰好 b 个单位的引导力,那么星球 x 对星球 z 就能有
恰好 a+b 个单位的引导力。 换言之,星球 x 对星球 y 的引导力可以是
x 到 y 的任意一条引导力路径的引导力总和。
人类利用现已发现的 n 个星球之间的引导力关系,在每个星球上
都建造了 p 个类型的传送枢纽,其中第 i 个类型的传送枢纽能够将人
从该星球传送到对该星球引导力为 2^(i-1)个单位的星球上。小 H 所
在的星球为 S,而他想去的星球为 T,他现在想知道他最少能传送几
次可以到达目的地呢?
【输入数据】
第一行五个正整数 n,m,p,S,T。
接下来 m 行,每行两个正整数“x y”表示一对引导力关系。
【输出数据】
输出只有一行,一个正整数,表示最少的传送次数。 如果不能到
达,请输出”-1”。
【样例输入】
4 4 3 1 4
1 1
2 1
3 2
4 3
【样例输出】
1
【数据范围】
对于 20%的数据, n<=5;
对于 40%的数据, n<=15;
另外 20%的数据, p<=10;
对于 100%的数据, 1<=n,m<=50, 1<=p<=31, 1<=S,T<=n。
【样例解释】
星球 1 对星球 1 的引导力为 1;
星球 2 对星球 1 的引导力为 2;
星球 3 对星球 1 的引导力为 3;
星球 4 对星球 1 的引导力为 4;
运用第 3 种传送枢纽可以直接从星球 1 传送到星球 4。

50分暴力代码如下:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<vector>
 4 #define INF 0x7fffffff
 5 using namespace std;
 6 int n,m,p,S,T,st[55],ct,a[55],b[55],ct2,pr[35],mx=INF;
 7 bool zh[55],flag,flag2;
 8 vector<int> G[55];
 9 void prework(){
10     int tmp=1; pr[0]=1;
11     for(int i=1;i<=30;i++) tmp*=2,pr[i]=tmp;
12 }
13 void dfs(int u,int fa){
14     st[++ct]=u;
15     if(u==T){
16         flag=true; a[++ct2]=ct-1;
17         for(int i=1;i<=ct;i++)
18             if(zh[st[i]]){printf("1");exit(0);}
19     }
20     if(u==S&&fa!=0){flag2=true;return;}
21     for(int i=0;i<G[u].size();i++){
22         if(G[u][i]==u) continue;
23         dfs(G[u][i],u);
24     }ct--;
25 }
26 int work(int x){
27     int ret=0;
28     while(x){
29         for(int i=p-1;i>=0;i--)
30             if(pr[i]<=x){x-=pr[i];ret++;break;}
31     }return ret;
32 }
33 int main()
34 {
35     freopen("magnet.in","r",stdin);
36     freopen("magnet.out","w",stdout);
37     prework();
38     scanf("%d%d%d%d%d",&n,&m,&p,&S,&T);
39     for(int i=1;i<=m;i++){
40         int x,y; scanf("%d%d",&x,&y);
41         G[y].push_back(x);
42         if(x==y) zh[i]=true;
43     }dfs(S,0);
44     if(!flag){printf("-1");return 0;}
45     if(!flag2){
46         for(int i=1;i<=ct2;i++) b[i]=work(a[i]);
47         for(int i=1;i<=ct2;i++)if(b[i]<mx) mx=b[i];
48         printf("%d",mx);
49         return 0;
50     }
51     printf("1");
52     return 0;
53 }

题解:还没写

技能(technique
【题目描述】
众所周知,小 C 有一块 n*n 的棋盘。
本来棋盘上有黑白两种颜色,其中从左上(1,1)到右下(n,n)的主对
角线上都是黑格。然而几天前小 W 叫来了几车面包人企图掀翻小 C
的棋盘,虽然小 C 机智地化解了面包人的进攻,但小 C 还是发现,
棋盘的格子被一股来自东方的神秘力量,打乱了。
于是小C开始修复他的棋盘,他的方法是:每次选择棋盘中不同
的两行(或两列),交换这两行(列)的颜色。小 C 并不苛求把棋盘
100%复原回原来的样子,只希望能够恢复原本的特征——“从左上
(1,1)到右下(n,n)的主对角线上都是黑格”即可。他希望知道这个方法
是否可行,毕竟有规律地还原事物也是一项重要的技能啊。
【输入数据】
第一行一个正整数 T, 表示数据组数。
接下来 T 组数据。每组数据第一行一个正整数 n,表示棋盘边长,
接下来 n 行,每行一个长度为 n 的 01 字符串,描述一个打乱后的 n*n
的棋盘。
【输出数据】
输出共 T 行,对于每组数据输出一行,如果能用题中所述方法把
棋盘特征复原,输出”Yes”,否则输出”No”。
【样例输入】
1 3
0 1 0
1 0 0
0 0 1
【样例输出】
Yes
【数据范围】
对于 20%的数据, n<=10;
对于 40%的数据, n<=50;
对于 60%的数据, n<=100;
另外 10%的数据,保证有某一行或某一列全为 0。
对于 100%的数据, 1<=n<=500, 1<=T<=4。
【样例解释】
交换 1,2 两行。 矩阵变为{{1,0,0},{0,1,0},{0,0,1}}。

题解:由于操作可逆,容易发现,题目可以转换为每行选一个1,使得每列都有一个1。这题就转换为二分图匹配,s向所有行连1,所有列向t连1,若a[i][j]=1,i行向j列连1,网络流即可。

代码如下:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #define MN 10005
 5 #define INF 0x7fffffff
 6 using namespace std;
 7 struct edge{int to,cap,next,rev;}e[MN*6];
 8 int s,t,n,m,cnt,head[MN],lev[MN],q[MN];
 9 void prework(){
10     cnt=0; memset(head,0,sizeof(head));
11     memset(q,0,sizeof(q));
12     memset(e,0,sizeof(e));
13 }
14 void ins(int u,int v,int w){
15     e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].cap=w;e[cnt].rev=cnt+1;
16     e[++cnt].to=u;e[cnt].next=head[v];head[v]=cnt;e[cnt].cap=0;e[cnt].rev=cnt-1;
17 }
18 bool bfs(){
19     memset(lev,-1,sizeof(lev));
20     int hd=0,tl=1;
21     lev[s]=0; q[hd]=s;
22     while(hd<tl){
23         int v=q[hd++];
24         for(int i=head[v];i;i=e[i].next)
25             if(e[i].cap>0&&lev[e[i].to]<0){
26                 lev[e[i].to]=lev[v]+1;
27                 q[tl++]=e[i].to;
28             }
29     }
30     if(lev[t]==-1) return false;
31     return true;
32 }
33 int dfs(int u,int f){
34     if(u==t) return f;
35     int used=0;
36     for(int i=head[u];i;i=e[i].next) {
37         if(e[i].cap>0&&lev[u]<lev[e[i].to]){
38             int w=dfs(e[i].to,min(f-used,e[i].cap));
39             if (w>0){
40                 e[i].cap-=w; e[e[i].rev].cap+=w; used+=w;
41                 if(used==f) break;
42             }
43         }
44     }
45     if(!used) lev[u]=-1;
46     return used;
47 }
48 int dinic(){
49     int flow=0;
50     while(bfs()) flow+=dfs(s,INF);
51     return flow;
52 }
53 void init(){
54     scanf("%d",&n); s=0; t=2*n+1;
55     for(int i=1;i<=n;i++)
56         for(int j=1;j<=n;j++){
57             char c; cin>>c;
58             if(c==‘1‘) ins(i,j+n,1);
59         }
60     for(int i=1;i<=n;i++) ins(s,i,1),ins(i+n,t,1);
61 }
62 int main()
63 {
64     freopen("technique.in","r",stdin);
65     freopen("technique.out","w",stdout);
66     int T; scanf("%d",&T);
67     while(T--){
68         prework(); init();
69         if(dinic()==n) printf("Yes\n");
70         else printf("No\n");
71     }
72     return 0;
73 }

社会主义西红柿(tomato)
【题目描述】
Kirby 是一个超级吃货, 其中 Maxim tomato 是 Kirby 最喜爱的食
物。 其他食物 Kirby 都可以强忍住不吃,唯有 Maxim tomato 对于他
来说,是不可抗拒的存在,这也就是 Kirby 现在被 Yin Yarn 变成毛线
扔在 Patch Land 上的原因。
所幸从 Yin Yarn 那里偷吃来的 Maxim tomato 给了 Kirby 很大的
增益,使得 Kirby 能够变化成很多东西进行更加快捷的行动。 Kirby
现在的任务是收集散落在 Patch Land 各处的宝石。 Patch Land 可以类
似地看做一根坐标轴, 一开始 Kirby 在原点,也是 Patch Land 的最左
端, Patch Land 的最右端位于 n。 Patch Land 上有 m 个地方散落着宝
石, 位置分别为 pi,该宝石的价值为 wi。 Kirby 在每个位置都有 k 种
行动方式,其中第 i 种行动方式是从当前位置向右跳到距离当前位置
为 di 的位置, 当然 Kirby 也可以选择就此收手,不做任何行动。 Kirby
每到一个位置都会捡起所在位置的所有宝石。所以 Kirby 想请你规划
一下路线,使他能获得的宝石价值总和最大。
“实在搞不懂为什么 Yin Yarn 的头顶会长着一颗 Maxim tomato,
真是越来越难猜测作者的想法了??” Kirby 无奈地喃喃自语。
【输入数据】
第一行一个正整数 n,m,k,表示 Patch Land 的长度、宝石个数和
行动种数;
第二行 k 个正整数,表示每种行动的移动距离 di;
接下来 m 行,每行两个整数, pi 和 wi,表示宝石的位置和价值。
【输出数据】
输出只有一行,最大的能获得的宝石价值总和。
【样例输入】
20 4 2
4 7
4 2
7 3
11 2
14 1
【样例输出】
5
【数据范围】
对于 10%的数据, n,m<=10, k<=3;
对于 25%的数据, n,m<=1000;
对于 40%的数据, n<=10^6;
另外 10%的数据, k=1;
另外 20%的数据, wi>0;
对于 100%的数据, 1<=n<=10^9, 1<=m<=10^5, 0<=pi<=n,
0<=|wi|<=10^9, 1<=k,di<=8, 保证 di 互不相同。
【样例解释】
先跳 7 格,再跳 4 格,依次经过 0,7,11。总和为 0+3+2=5。

题解:还没写

时间: 2024-10-11 09:43:23

2017/11/1模拟赛的相关文章

2017/11/3模拟赛

块(block)[问题描述]拼图达人小 C 手里有 n 个 1*1 的正方形方块, 他希望把这些方块拼在一起, 使得拼出的图形周长最小, 要求方块不能重叠. 擅长拼图的小 C 一下就求出了这个周长, 顺便他想考考你会不会求.[输入格式]多组数据, 第一行一个正整数 T, 表示数据组数.接下来 T 行, 每行一个正整数 n, 表示方块数.[输出格式]输出 T 行, 每行一个正整数, 表示答案.[样例输入]3 4 1122[样例输出]81420[数据范围]对于 20%的数据, n<=20:对于 40

2017 11 6模拟赛T1

作为一个毒瘤出题人(wzy:我不是毒瘤出题人,这些题明明很水的),wzy的题干十分复杂,但是把题意简化之后,相当简单粗暴... 求首项为1,等比为m,项数为t的等比数列的和,答案对k取模 不保证m与k互质 如果m与k互质的话,用等比数列的求和公式在求个逆元就能解决了,但是本题显然不能,于是必须考虑不含有除法的算法 于是就有了分治求等比数列和的办法. 设s(x)为等比数列的第n项 由等比数列的性质得到s(y)=s(x)*m^(y-x) (y>x) 将一个长度为2r的等比数列拆分成登场的两部分,对应

2017.6.11 校内模拟赛

题面及数据及std(有本人的也有原来的) :2017.6.11 校内模拟赛 T1 自己在纸上模拟一下后就会发现 可以用栈来搞一搞事情 受了上次zsq 讲的双栈排序的启发.. 具体就是将原盘子大小copy一下排个序 用两个指针维护两个数组(原数据 和 排序后的数据), 即分为1数据和2数组 将小于1指针指向的数据的2数组中的数据全部压入栈中 后进行消除, 将栈栈顶元素与当前1数组中的1指针指向的元素进行比较 相同则消除 后重复过程 直至指针超过N 后判断一下是否两个指针都超过了N... #incl

2017 9 11 noip模拟赛T2

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=205; int map[N][N]; int d[N],tag[N],book[N],f[N]; int n,m; void work(int x) { memset(d,63,sizeof(d)); memset(book,0,sizeof(book)); memset(f,0,sizeof(

11.27 模拟赛

并没有人做的模拟赛... 出题人hx,,, T1:就是上一道矩阵乘法 数学题 T2: 一个数列中 一个区间满足,存在一个k(L <= k <= R),并且对于任意的i (L <= i <= R),ai都能被ak整除 这样的一个特殊区间 [L, R]价值为R - L 想知道序列中所有特殊区间的最大价值是多少,而有多少个这样的区间呢 这些区间又分别是哪些呢 输出每个区间的L 思路: 用两个ST表分别求一段区间的gcd和最小值 然后可以二分答案 check的时候枚举左端点,判断在这段区间

2017 7.22 模拟赛

最水的一次模拟赛.. 点击查看题目 T1 求最后K位  那前面的数是没有比要求的 , 我们就把 10k 作为模数 ,对答案进行取模 就好了  #include <ctype.h> #include <cstdio> #define N 100005 typedef long long LL; void read(LL &x) { x=0;bool f=0; register char ch=getchar(); for(;!isdigit(ch);ch=getchar())

11.4 模拟赛

终于AK了,虽然第三题主要是搞月想出来的 T1: n个1*1的小方块,把这些小方块拼成一个图形,使这个图形周长最小 思路: 枚举拼成长方形的长为i,宽为n/i 可得面积 (i+n/i+(bool)(n%i))*2 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cmath> 6 #include<cstr

2017 无奈的模拟赛

悲剧的开始~~~~ 竞赛时间:????年??月??日??:??-??:?? 题目名称 第二题 死亡 凝视 名称 two death eyesight 输入 two.in death.in eyesight.in 输出 two.out death.out eyesight.out 每个测试点时限 1 秒 1 秒 1 秒 内存限制 512MB 512MB 512MB 测试点数目 10 10 10 每个测试点分值 10 10 10 是否有部分分 无 无 无 题目类型 传统 传统 传统 注意事项(请务必

2017/9/13模拟赛

粉饰(decorate) [题目描述] 小D有一块被分为n*m个格子的矩形鱼片.为了装饰鱼片,小D决定给每个格子上色.由于小D很喜欢红白,所以小D给每个格子涂上了红色或白色,第i行第j列的格子颜色记为c[i,j].涂完之后,小D想评估这块鱼片的"XY值".我们定义一个有序无重复三元格子组{(x1,y1),(x2,y2),(x3,y3)}为"XY组"当且仅当: |(x1-x2)*(y1-y2)|+|(x3-x2)*(y3-y2)|=0   (c[x1,y1]-c[x2