洛谷八连测2017R1

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷八连测2017R1相关的知识,希望对你有一定的参考价值。

SAC E#1 - 一道中档题 Factorial

题目背景

SOL君(炉石主播)和SOL菌(完美信息教室讲师)是好朋友。

题目描述

SOL君很喜欢阶乘。而SOL菌很喜欢研究进制。

这一天,SOL君跟SOL菌炫技,随口算出了n的阶乘。

SOL菌表示不服,立刻就要算这个数在k进制表示下末尾0的个数。

但是SOL菌太菜了于是请你帮忙。

输入输出格式

输入格式:

本题包含多组数据。

每组输入仅包含一行:两个整数n,k。

输出格式:

对于每组输入,输出一个整数:n!在k进制下后缀0的个数。

输入输出样例

输入样例#1:
10 40
输出样例#1:
2

说明

对于20%的数据,n <= 1000000, k = 10

对于另外20%的数据,n <= 20, k <= 36

对于60%的数据,n <= 10^15,k <= 10^12

对于100%的数据,n <= 10^18,k <= 10^16

 

SAC E#1 - 一道简单题 Sequence2

题目背景

小强和阿米巴是好朋友。

题目描述

小强喜欢数列。有一天,他心血来潮,写下了三个长度均为n的数列。

阿米巴也很喜欢数列。但是他只喜欢其中一种,波动数列。

阿米巴把他的喜好告诉了小强。小强便打算找出这三个数列内的最长波动数列。

也就是说,如果我们将三个数列记做a[n][3],他必须要构造一个二元组序列:<p[i], q[i]>,使得对于任何 i>1 有:

p[i] > p[i-1]

若q[i] = 0,a[p[i]][q[i]] >= a[p[i-1]][q[i-1]]

若q[i] = 1,a[p[i]][q[i]] <= a[p[i-1]][q[i-1]]

若q[i] = 2,只要保持段内同向即可(就是对于连续的一段q[i]=2,要么都有a[p[i]][q[i]] >= a[p[i-1]][q[i-1]],要么都有a[p[i]][q[i]] <= a[p[i-1]][q[i-1]])。

小强希望这个二元组序列尽可能长。

提示:当q[i] != q[i-1]时,数列的增减性由q[i]而非q[i-1]决定。

清晰版题目描述

小强拿到一个3×n的数组,要在每一列选一个数(或者不选),满足以下条件:

1.如果在第一行选,那它必须大于等于上一个数

2.如果在第二行选,那么必须小于等于上一个数

3.如果在第三行选,对于连续的一段在第三行选的数,必须满足方向相同(都小于等于上一个数或者都大于等于上一个数)

输入输出格式

输入格式:

输入包含4行。

第一行一个数n,表示数列长度。

第2、3、4行,每行n个整数,分别表示三个数列。

输出格式:

输出仅包含一个整数,即最长波动数列的长度。

输入输出样例

输入样例#1:
6
1 2 3 6 5 4
5 4 3 7 8 9
1 2 3 6 5 4
输出样例#1:
6

说明

对于20%的数据,n <= 10, m <= 1000

对于60%的数据,n <= 1000, m <= 1000

对于100%的数据, n <= 100000, m <= 1000000000

其中m = max|a[i]|

样例解释:

取第三行1 2 3(增),然后取第1行6(增),然后取第三行5 4(减),长度为6。

 

E#1 - 一道大水题 Knight

题目背景

毒奶色和F91是好朋友。

题目描述

他们经常在一起玩一个游戏,不,不是星际争霸,是国际象棋。

毒奶色觉得F91是一只鸡。他在一个n×n的棋盘上用黑色的城堡(车)、骑士(马)、主教(象)、皇后(副)、国王(帅)、士兵(卒)摆了一个阵。

然而F91觉得毒奶色是一只鸡。他发起了挑战:他要操纵一个白色骑士,不经过任何一个棋子的攻击范围(F91可以连续行动,而毒奶色的棋子不会动,除非白骑士进入了对方的攻击范围),并击杀毒奶色的国王(即进入黑国王所在的位置)。

请告诉F91他最少需要多少步骤来完成这一项壮举。

注意:

1.当F91的白骑士走到毒奶色的棋子所在的格子上的时候,会击杀(吃掉)该棋子。这个棋子也就不再对F91的白骑士有威胁了。

2.如果白骑士开场就在黑子的攻击范围内,则立刻被击杀、F91立刻失败。

3.即使白骑士在攻击王的瞬间进入了其他棋子攻击范围(即其他棋子“看护”着王所在的格子),依然算F91获胜。

攻击范围:

城堡:横、竖方向所有位置,直到被一个其他棋子阻拦。

..#..
..#..
##C##
..#..
..#..

骑士:横2竖1或者横1竖2的所有位置(最多8个,类似日字)。

.#.#.
#...#
..K..
#...#
.#.#.

主教:斜向(45°)所有位置,直到被一个其他棋子阻拦。

#...#
.#.#.
..B..
.#.#.
#...#

皇后:城堡和主教的结合体(既能横/竖向攻击,也能45°角斜向攻击,直到被其他棋子阻挡)。

#.#.#
.###.
##Q##
.###.
#.#.#

国王:身边8连通位置的8个格子。

.....
.###.
.#X#.
.###.
.....

士兵:左下方/右下方(45°)的格子(最多2个)。

.....
.....
..P..
.#.#.
.....

其中字母表示棋子类型,参考输入格式。

‘#’表示可攻击范围。

输入输出格式

输入格式:

输入包含多组数据。

每一组数据中,第一行一个整数n表示棋盘规模。

接下来n行,每行一个长度为n的字符串。描述棋盘的格局。

其中:

.表示空

O表示白骑士

C表示黑城堡

K表示黑骑士

B表示黑主教

Q表示黒皇后

X表示黑国王

P表示黑士兵

输出格式:

对于每一个测试数据,每行输出一个整数,表示F91的最小步数。

如果无论F91如何行动也无法击杀黑国王,输出-1。

输入输出样例

输入样例#1:
8
...X....
........
........
........
........
........
........
......O.
输出样例#1:
4
输入样例#2:
8
......X.
........
.O......
...P.Q.C
.....B..
........
...K....
........
输出样例#2:
7

说明

输入最多包含5组数据。

对于20%的数据,毒奶色只有国王。n <= 8。

对于30%的数据,毒奶色只有国王、骑士。n <= 8。

对于60%的数据,毒奶色只有国王、骑士、王后。n <= 50。

对于100%的数据,毒奶色可以有全套16颗棋子(2城堡,2骑士,2主教,1后,1王,8兵)。n <= 50。

温馨提示:

时间限制可能比想象之中还要更紧一点,请注意实现细节以保证性能。

样例2解释:

一种可行的做法是:

......X.
.3..6...
.O5.....
4.2P.Q.C
1....B..
........
...K....
........

T1:

骗分解法:

技术分享
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<vector>
 7 #define MAXN 1000005
 8 #define ll long long
 9 #define pii pair<int,int>
10 using namespace std;
11 int b[MAXN];
12 int p[MAXN];
13 ll n,k;
14 vector<int> s;
15 void solve(){
16     memset(b,0,sizeof(b));
17     memset(p,0,sizeof(p));
18     s.clear();
19     for(int j=2;j<=n;j++){
20         int m=j;
21         int t=sqrt(m);
22         for(int i=2;i<=t;i++){
23             while(!(m%i)){
24                 b[i]++;
25                 m/=i;
26             }
27         }
28         if(m!=1){
29             b[m]++;
30         }    
31     }
32     ll t=sqrt(k);
33     for(int i=2;i<=t;i++){
34         if(!(k%i)){
35             s.push_back(i);
36             while(!(k%i)){
37                 p[i]++;
38                 k/=i;
39             }            
40         }
41     }
42     if(k!=1){
43         s.push_back(k);
44         p[k]++;
45     }
46     int ans=0x7f7f7f7f;
47     for(int i=0;i<s.size();i++){
48         ans=min(ans,b[s[i]]/p[s[i]]);
49     }
50     printf("%d\\n",ans);
51 }
52 int main()
53 {
54     while(~scanf("%lld%lld",&n,&k)){
55         solve();
56     }
57     return 0;
58 }
Code1-1

思路是对k进行质因数分解,然后对于k的每个因数p,计算n!中包含多少个p,即分解为n!=x*p^e的形式

e=x/p + x/p^2 + x/p^3 + ……

然后即可求解

暴力分解k:

技术分享
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<vector>
 6 #define ll long long
 7 #define pll pair<ll,ll>  
 8 using namespace std;
 9 ll n,k;
10 vector<pll > s;
11 ll i,cnt,ans,x,p,sum,t;
12 void solve(){
13     s.clear();
14     for(i=2;i*i<=k;i++){
15         cnt=0;
16         while(!(k%i)){
17             k/=i;
18             cnt++;
19         }
20         if(cnt){
21             s.push_back(make_pair(i,cnt));
22         }
23     }
24     if(k){
25         s.push_back(make_pair(k,1));
26     }
27     ans=0x7fffffffffffffffll;
28     for(i=0;i<s.size();i++){
29         x=s[i].first,p=s[i].second;
30         sum=0;
31         for(t=x;t<=n;t*=x){
32             sum+=(n/t);
33         }
34         ans=min(ans,sum/p);
35     }
36     printf("%lld\\n",ans);
37 }
38 int main()
39 {
40     while(~scanf("%lld%lld",&n,&k)){
41         solve();
42     }
43     return 0;
44 }
Code1-2

正解是用rho分解


T2:

技术分享

方程如上

可以用离散化+树状数组或者线段树维护,单调栈应该也可以

离散化之后的数组应该开3倍

技术分享
  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<algorithm>
  4 #include<cstring>
  5 #define MAXN 100010
  6 #define MAXM 100010*3
  7 using namespace std;
  8 struct Node{
  9     int Val;
 10     int x,y;
 11     Node(int p1=0,int p2=0,int p3=0){
 12         Val=p1,x=p2,y=p3;
 13     }
 14 }vs[MAXM];
 15 bool comp(const Node &p1,const Node &p2){
 16     return (p1.Val<p2.Val);
 17 }
 18 int a[4][MAXN];
 19 int n;
 20 int top;
 21 int cnt=1;
 22 //query is the opposite of update
 23 int max_bigger(int d[],int k){
 24     int ret=0;
 25     while(k<=cnt){
 26         ret=max(d[k],ret);
 27         k+=(k&-k);
 28     }
 29     return ret;
 30 }
 31 int max_fewer(int d[],int k){
 32     int ret=0;
 33     while(k>0){
 34         ret=max(d[k],ret);
 35         k-=(k&-k);
 36     }
 37     return ret;
 38 }
 39 void update_bigger(int d[],int k,int x){
 40     while(k>0){
 41         d[k]=max(d[k],x);
 42         k-=(k&-k);
 43     }
 44 }
 45 void update_fewer(int d[],int k,int x){
 46     while(k<=cnt){
 47         d[k]=max(d[k],x);
 48         k+=(k&-k);
 49     }
 50 }
 51 int read(){
 52     int x=0,f=1;char ch=getchar();
 53     while(ch<0||ch>9){if(-==ch)f=-1;ch=getchar();}
 54     while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
 55     return x*f;
 56 }
 57 int f[MAXN],g[MAXN],h1[MAXN],h2[MAXN];
 58 int da1[MAXM],da2[MAXM];
 59 int db1[MAXM],db2[MAXM];
 60 int dc1[MAXM],dc2[MAXM];
 61 int dd1[MAXM],dd2[MAXM];
 62 int main()
 63 {
 64 //    freopen("data.in","r",stdin);
 65 //    freopen("my.out","w",stdout);
 66     n=read();
 67     for(int j=1;j<=3;j++){
 68         for(int i=1;i<=n;i++){
 69             a[j][i]=read();
 70             vs[++top]=Node(a[j][i],j,i);
 71         }        
 72     }
 73     sort(vs+1,vs+top+1,comp);
 74     for(int i=1;i<=top;i++){
 75         if(vs[i].Val!=vs[i-1].Val){
 76             cnt++;
 77         }
 78         a[vs[i].x][vs[i].y]=cnt;
 79     }
 80     for(int i=1;i<=n;i++){
 81         int t=0;
 82         t=max(t,max_fewer(da1,a[1][i]));
 83         t=max(t,max_fewer(db1,a[1][i]));
 84         t=max(t,max_fewer(dc1,a[1][i]));
 85         t=max(t,max_fewer(dd1,a[1][i]));
 86         f[i]=t+1;
 87         t=0;
 88         t=max(t,max_bigger(da2,a[2][i]));
 89         t=max(t,max_bigger(db2,a[2][i]));
 90         t=max(t,max_bigger(dc2,a[2][i]));
 91         t=max(t,max_bigger(dd2,a[2][i]));
 92         g[i]=t+1;
 93         t=0;
 94         t=max(t,max_fewer(da1,a[3][i]));
 95         t=max(t,max_fewer(db1,a[3][i]));
 96         t=max(t,max_fewer(dc1,a[3][i]));
 97         h1[i]=t+1;
 98         t=0;
 99         t=max(t,max_bigger(da2,a[3][i]));
100         t=max(t,max_bigger(db2,a[3][i]));
101         t=max(t,max_bigger(dd2,a[3][i]));
102         h2[i]=t+1;
103         update_fewer(da1,a[1][i],f[i]);
104         update_fewer(db1,a[2][i],g[i]);
105         update_fewer(dc1,a[3][i],h1[i]);
106         update_fewer(dd1,a[3][i],h2[i]);
107         update_bigger(da2,a[1][i],f[i]);
108         update_bigger(db2,a[2][i],g[i]);
109         update_bigger(dc2,a[3][i],h1[i]);
110         update_bigger(dd2,a[3][i],h2[i]);
111     }
112     int m=0;
113     for(int i=1;i<=n;i++){
114         m=max(max(f[i],g[i]),max(h1[i],h2[i]));
115     }
116     printf("%d\\n",m);
117     
118 //    for(int i=1;i<=n;i++){
119 //        printf("%d ",f[i]);
120 //    }
121 //    printf("\\n");
122 //    for(int i=1;i<=n;i++){
123 //        printf("%d ",g[i]);
124 //    }
125 //    printf("\\n");
126 //    for(int i=1;i<=n;i++){
127 //        printf("%d ",h2[i]);
128 //    }
129 //    printf("\\n");
130 //    for(int i=1;i<=n;i++){
131 //        printf("%d ",h1[i]);
132 //    }
133 //    printf("\\n");    
134     return 0;
135 }
Code2

 

 

 









以上是关于洛谷八连测2017R1的主要内容,如果未能解决你的问题,请参考以下文章

洛谷八连测R5whzzt-Confidence

洛谷八连测R5whzzt-Warmth

洛谷八连测R5 题解

洛谷 八连测 R4

洛谷八连测R6

洛谷八连测R6