XJOI 郎思轲模拟题

今天比赛的是郎思轲出的模拟题,比较偏数学.

全国青少年奥林匹克联赛

CCF-NOIP 2017模拟试题

提高组(复赛)day1

竞赛时间:210分钟

命题:郎思轲

题目一览:


题目名称


不定长数组


台球游戏


对称的多项式


题目类型


传统型


传统型


传统型


目录


vector


billiards


poly


可执行文件名


vector


billiards


poly


输入文件名


vector.in


billiards.in


poly.in


输出文件名


vector.out


billiards.out


poly.out


每个测试点时限


1.0秒


2.0秒


2.0秒


内存限制


512MB


512MB


512MB


测试点数目


20


20


20


每个测试点分值


5


5


5

提交源程序文件名:


对于C++   语言


vector.cpp


billiards.cpp


poly.cpp


对于C     语言


vector.c


billiards.c


poly.c


对于Pascal语言


vector.pas


billiards.pas


poly.pas

编译选项:


对于C++   语言


-O2 -lm


-O2 -lm


-O2 -lm


对于C     语言


-O2 -lm


-O2 -lm


-O2 -lm


对于Pascal语言


-O2


-O2


-O2

注意事项:

1.文件名(程序名和输入输出文件名)必须使用英文小写。

2.除非特殊说明,结果比较方式均为忽略行末空格及文末回车的全文比较。

3.C/C++中函数main()的返回值类型必须是int,程序正常结束时的返回值必须是0。

1. 不定长数组

vector

【问题描述】

 Description

 

 小A是一个C++初学者,最近他学会了不定长数组vector的使用方法,于是他很兴奋,就把他的好多文件存到了好多vector中。

最终小A得到了n个vector,每个vector都不是空的,每个vector的类型都为字符类型char,一个vector代表小A的一个文件;由于小A只喜欢简洁的英文小写字母,因此他的文件中仅包含英文小写字母。

接下来小A发现他每次只能对一个vector v[i] 进行这一些操作:

l v[i].push_back(ch) 在vector v[i]后添加一个字符ch

l v[i].pop_back() 在vector v[i]后删除一个字符

l v[i][j]=ch 将vector v[i]的第j+1个字符修改为ch

现在小A觉得这么多不同的文件看起来太杂乱了,因此他想对一些文件进行修改,从而使得所有的文件都相同;他想知道他最少要做几次操作能使所有的vector均相同(可以把vector修改为空,vector的长度也没有上限),请你帮他计算这个结果。

在修改文件之前,小A还想知道把任意两个vector修改为相同需要的操作数(每一次操作你可以任选一个vector进行)。设为vector[i]与vector[j]修改为相同需要的操作数,你只需要回答

的值。

注:如果你对C++或者不定长数组不熟悉,你只需对题意有大致理解即可,这并不会影响解题。

【输入格式】

 Input

   从文件vector.in中读取数据;

输入文件第一行一个正整数n,表示vector的个数;

接下来n行,第i行一个仅包含英文小写字母的字符串,第j个字符表示vector[i]的第j个字符;

最后一行为两个0或1的数k1,k2,含义见输出格式。

由于输入文件可能比较大,建议C++选手不要使用过慢的读入方式。

【输出格式】

 Output

输出到文件vector.out中;

输出共k1+k2行;

k1=1,输出一行,为上文所述的        的值;

接下来,若k2=1,输出一行,即为使所有的vector均相同的最少操作次数。

【输入样例1

 Sample Input #1

3

he

she

him

1 1

【输出样例1

 Sample Output #1

8

5

【输入输出样例1说明】

在这个样例中,你两个询问都需要回答。

对于第一个询问,可以知道=2,操作方案为:

step1:v[1][1]=i,操作后vector[1]表示的串为“hi”

step2v[i].pop_back(),操作后vector[2]表示的串也为“hi”

可以知道2步是最少的方案。

以此类推可计算出=3,=3,因此答案为2+3+3=8;

对于第二个询问,可以把所有的字符串均改为“hi”;

此时答案为1+3+1=5,可以知道5为最优解。

【输入样例2

 Sample Input #2

10

also

rate

rateg

d

edee

edge

lae

reai

aslie

ead

0 1

【输出样例2

 Sample Output #2

29

 

【输入输出样例3、输入输出样例4

见选手文件下的vector3.in/vector3.ans、vector4.in/vector4.ans

其中vector3.in数据范围同第3个测试点,vector4.in数据范围同第16个测试点。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

【数据范围与约定】

l 对于100%的数据,n≥2,不存在空字符串。


测试点编号


n


len


maxlen


k1


k2


1


≤10


≤10


≤5


1


1


2


3


=100


=500


=5


4


5


=300


=30000


=100


1


0


6


≤1000


7


≤5000


≤10000


≤100


8


≤10000


9


≤100000


≤1000000


≤1000000


10


11


=300


=30000


=100


0


1


12


≤1000


≤1000


≤1000


13


14


≤100000


≤1000000


≤1000000


15


16


≤100000


≤1000000


≤1000000


1


1


17


18


19


20

 

注:表示所有vector的元素个数之和,maxlen表示所有vector中最大的元素个数。

 

 

 

 

 

 

 

2. 台球游戏

billiards

【问题描述】

 Description

最近小B迷上了台球游戏,这个游戏在一张矩形球桌上进行,基本规则是将球打进球桌边缘上的球洞就会得分;为了让题目更有趣,在本题中我们认为球桌大小、球洞位置和球洞个数是不确定的,但保证球桌的四角均有球洞,在球桌长边上的两个相邻球洞距离都相等,短边上的两个相邻球洞距离也都相等。

我们记球桌长边为n,短边为m,长边上的两个相邻球洞距离为,长边上的两个相邻球洞距离为,下图表示了n=8,m=6,=4,=2时的球桌的形态 (黑点表示球洞):

为了表示方便,我们把所有球洞进行标号:先将矩形下边界的球洞从左上角至右上角分别标号为到,然后同样将下边界的球洞标为到;最后若,将左边界、右边界除角上的球洞从上到下依次标号为到,到,你可以参照上图来帮助理解标号方式。

现在,球桌左上角有一只台球(注意:虽然球桌左上角一定有球洞,但开始时球并不会进入这个洞),这只台球会沿一定角度射出,碰到边缘会反弹(反弹时入射角等于反射角),你可以认为台球的轨迹不会弯曲,但台球碰到边缘k次(开始时在左上角不算在内)后会立即停下,小B想知道,对于给定的n,m,  ,  ,k和刚开始射出的角度,台球最终会进入哪个洞。

【输入格式】

 Input

   从文件billiards.in中读取数据;

第一行一个整数T表示数据组数;

接下来T行,每行7个正整数n,m,  ,  ,a,b,k,其中n,m,  ,  ,k的含义为题目描述所述,a,b表示台球初始射出的轨迹同的夹角,记该夹角为,则。

【输出格式】

 Output

输出到文件billiards.out中;

输出T行,对于每个数据输出台球最终掉进的球洞编号以及球碰到边缘次数(开始时在左上角不算在内);若直到台球停下球还没有进洞,则输出-1。

【输入样例1

 Sample Input #1

3

8 6 4 2 1 1 2

8 6 4 2 1 1 1

9 5 3 5 1 1 20

【输出样例1

 Sample Output #1

D1 1

-1

B1 3

【输入输出样例1说明】

对于第一、二个数据,球桌形态及台球轨迹如下左图

 

根据上左图可以看出,第一个数据台球反弹1次进入了球洞,而第二个数据台球撞击一次后停了下来而没有进洞;

根据上右图可以看出,第三个数据台球反弹3次后进了球洞。

【输入输出样例2、输入输出样例3

见选手文件下的billiards2.in/billiards2.ans、billiards3.in/billiards3.ans

其中billiards2.in数据范围同第6个测试点,billiards3.in数据范围同第16个测试点。

 

【数据范围与约定】

l 对于100%的数据,,,mn, 保证a,b互质。


测试点编号


n,m


a,b


k


T


p


1


≤10


=1


=1


≤10


1


2


≤2


3


≤10


4


≤100


≤100


5


≤1000


≤1000


≤1000


6


≤10000


≤10000


≤50


0


7




8


≤100000


9


10


=1


11



1


12


13



14


15


16


≤100000


0


17


18


19


20

注:当时,p=1,否则p=0。

 

 

3. 对称的多项式

poly

【问题描述】

 Description

小C现在有一个数n和一个系数均在模n+1意义下的次数界为n

的多项式,但小C并不喜欢这个多项式,因为这个多项式

并不是对称的,而小C希望对这个多项式进行变形,成为另一个系数均在模p意义下的对称的多项式;

小C的变形方式如下:

变形得到的多项式                               ,如n=4,原多项式f(x)=3+2+x+4,则g(x)=((3+4+2) mod 5)+((2+1+2) mod 5)+((2+1+2) mod 5)x+((3+4+2) mod 5)=4+4。

现在小C给了你原多项式f(x),请你帮他转成对称的多项式g(x)。

小C还发现了一个性质:给出多项式,能求出x取1到n时的多项式在模n+1意义下的值,而给出这些值也能唯一确定一个系数在模域下的次数界为n的多项式,因此他决定给你原多项式x取1到nn个值,而你只要告诉他答案多项式分别在x取1到n时模n+1意义下的值就可以了。

【输入格式】

 Input

   从文件poly.in中读取数据;

第一行一个正整数n,,题目描述中已经解释过n的含义;

接下来n个整数,第i个整数表示当xi时原多项式f(x)在模n+1意义下的值f(i)。

【输出格式】

 Output

输出到文件poly.out中;

输出一行,n个整数,第i个整数表示当xi时答案多项式g(x)在模n+1意义下的值g(i),注意0≤g(i)≤n

【输入样例1

 Sample Input #1

4

0 3 1 2

【输出样例1

 Sample Output #1

3 1 2 0

【输入输出样例1说明】

该样例对应于题目描述中举的例子。

【输入样例2

 Sample Input #2

6

1 2 1 2 1 2

【输出样例2

 Sample Output #2

0 3 6 6 4 0

【输入输出样例3、输入输出样例4

见选手文件下的poly3.in/poly3.ans、poly4.in/poly4.ans

其中poly3.in数据范围同第4个测试点,poly4.in数据范围同第11个测试点。

【数据范围与约定】

l 对于100%的数据,0≤ f(i)≤ n


测试点编号


n


测试点编号


n


1


=6


11


=4000


2


=16


12


3


=22


13


=49998


4


=100


14


5


=232


15


6


=250


16


7


=996


17


8


=2332


18


=100002


9


19


=500008


10


20

比赛时只做了前两题

第一题是一个暴力统计,没什么好讲

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100010,LEN=1000100;
vector<char>s[N];
char b[LEN];
int n,maxlen,ch[LEN][26],len[N],k1,k2,tot[LEN],righ[LEN],rig[LEN];
ll calc1(){
    ll res=0;
    for (int i=1; i<=n; i++){
        for (int j=0; j<len[i]; j++) res+=n-ch[j][s[i][j]-‘a‘];
        res+=tot[len[i]];
    }
    return res>>1;
}
ll calc2(){
    ll res=tot[0],re=0;
    for (int i=0; i<maxlen; i++){
        re+=n-ch[i][righ[i]];
        res=min(res,re+tot[i+1]);
    }
    return res;
}
int main(){
    //freopen("vector3.in","r",stdin);
    //freopen("A.out","w",stdout);
    scanf("%d",&n);
    for (int i=1; i<=n; i++){
        scanf("%s",b);
        for (len[i]=0; b[len[i]]; len[i]++){
            s[i].push_back(b[len[i]]);
            if (++ch[len[i]][b[len[i]]-‘a‘]>rig[len[i]]){
                rig[len[i]]=ch[len[i]][b[len[i]]-‘a‘];
                righ[len[i]]=b[len[i]]-‘a‘;
            }
            tot[len[i]]++;
        }
        maxlen=max(maxlen,len[i]);
    }
    for (int i=maxlen-2; i>=0; i--) tot[i]+=tot[i+1];
    scanf("%d%d",&k1,&k2);
    if (k1) printf("%lld\n",calc1());
    if (k2) printf("%lld\n",calc2());
    return 0;
}

第二题需要每弹一次把地图展开,因为会爆longlong所以用__int128水过

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF=1e18;
ll n,m,n0,m0,a,b,k,zq1,zq2,ind1,ind2;
char ch1,ch2;
int t;
long double p=1;
void solvep0(){
    ll A=a*m,B=n0*b,ceng=B/__gcd(A,B),len=(ll)p*A*ceng/b;
    zq1=(len%n==0?len/n-1:len/n),ind1=len%n/n0;
    if (ind1==0&&zq1%2==0) ind1=n/n0;
    if (ind1&&(zq1&1)) ind1=n/n0-ind1;
    zq1+=ceng-1;
    ch1=ceng&1?‘B‘:‘A‘;
}
void solvep1(){
    ll A=b*n,B=m0*a,ceng=B/__gcd(A,B),len=(ll)p*A*ceng/a;
    zq2=(len%m==0?len/m-1:len/m),ind2=len%m/m0;
    if (ind2==0&&zq2%2==0) ind2=m/m0;
    if (ind2&&(zq2&1)) ind2=m/m0-ind2;
    zq2+=ceng-1;
    ch2=ceng&1?‘D‘:‘C‘;
}
int main(){
    //freopen("billiards3.in","r",stdin);
    //freopen("B.out","w",stdout);
    scanf("%d",&t);
    while (t--){
        scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&m,&n0,&m0,&a,&b,&k);
        if (m0==m){
            solvep0();
            if (zq1<k) printf("%c%lld %lld\n",ch1,ind1,zq1); else puts("-1");
        }else{
            solvep0();
            solvep1();
            if (zq1<=zq2&&zq1<k) printf("%c%lld %lld\n",ch1,ind1,zq1);
            else if (zq2<zq1&&zq2<k) printf("%c%lld %lld\n",ch2,ind2-1,zq2);
            else puts("-1");
        }
    }
}

第三题是一个奇妙的变换

#include<bits/stdc++.h>
using namespace std;
const int N=500009;
int n,f[N],p;
inline int pow(int x,int y){
    int res=1;
    while (y){
        if (y&1) res=1ll*res*x%(n+1);
        x=1ll*x*x%(n+1);
        y>>=1;
    }
    return res;
}
int main(){
    scanf("%d",&n);
    for (int i=1; i<=n; i++) scanf("%d",&f[i]);
    printf("%d ",(f[1]+f[1]+2*n)%(n+1));
    for (int i=2; i<=n; i++){
        p=pow(i,n-1);
        printf("%d ",(f[i]+1ll*p*f[p]%(n+1))%(n+1));
    }
}
时间: 2024-12-25 12:23:31

XJOI 郎思轲模拟题的相关文章

xjoi2016模拟题1

星期天下午被某个sb叫去做xjoi模拟题. 发现自己好弱.STL不熟. T1 一开始是想把每一列的最大平均值算出来,然后每一列相加在算平均值,然后发现这是错误的想法,于是华丽丽的10分. 正解:二分枚举最大平均值,判断是否合法. #include<cstdio>#include<cstdlib>#include<cstring>#define max(x,y) (x>y?x:y)const int N=9001000;long long sum[N];int n,

HDU 4028 The time of a day STL 模拟题

暴力出奇迹.. #include<stdio.h> #include<iostream> #include<algorithm> #include<vector> #include<cmath> #include<queue> #include<set> #include<map> using namespace std; #define ll __int64 #define N 42 ll n,m,ans;

cf428c 模拟题

这题说的是给了 n个数然后又 k次 的交换任意位置的 数字的机会  计算最长的连续子序列的和 这要撸  模拟整个 过程 并不能就是算最长的递增序列 如果只是 找最长的 和序列的 话 会存在 很多问题 在替换的时候 每一个决策 都影响着 下一个决策  这样 存在谁与谁替换 这样的状态有 200!种    那就枚举每个区间这样就可以使得 我们所用替换方法得当  因为在替换中我们进行替换是对不同区间的 操作 比如 在替换序列之内的 数字的时候 其实操作的就是不同的区间 与外面的序列进行替换的时候 操作

TOJ1290 Poker Hands 模拟题

寒假期间抽空做的一道模拟题 难度不算大,把每种牌型分开处理,可以合并的步骤考虑合并. 代码比较丑陋,首次尝试Sport Programming的风格,结果搞了个不伦不类(手动笑哭) 1 #include <algorithm> 2 #include <bitset> 3 #include <cctype> 4 #include <complex> 5 #include <cstdio> 6 #include <cstring> 7 #

hdu 5641 King&#39;s Phone(暴力模拟题)

Problem Description In a military parade, the King sees lots of new things, including an Andriod Phone. He becomes interested in the pattern lock screen. The pattern interface is a 3×3 square lattice, the three points in the first line are labeled as

HDU 2414 Chessboard Dance(模拟题,仅此纪念我的堕落)

题目 模拟题也各种wa,我最近真的堕落了,,,,,智商越来越为负数了!!!!!!!! #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; char mp[10][10]; int d=-1;//0shang,1xia,2zuo,3you int x,y;//weizhi int weizhi(int i,int j) { if(mp[i][j]=='<'){x=

HDU 4930 Fighting the Landlords(扯淡模拟题)

Fighting the Landlords 大意: 斗地主....   分别给出两把手牌,肯定都合法.每张牌大小顺序是Y (i.e. colored Joker) > X (i.e. Black & White Joker) > 2 > A (Ace) > K (King) > Q (Queen) > J (Jack) > T (10) > 9 > 8 > 7 > 6 > 5 > 4 > 3. 给你8种组合:1.

锦程网考试由试题从模拟题中批量找出答案,Python

jincin的考试又来了,像往常一样会先有模拟题发下来,而考试题目几乎都在里面原题. 本来是,在考试时,把题目一题一题地在模拟题里搜,但觉得太累了. 于是写了一个Python的脚本批量查找,用到正则,由于不知道行尾是\r还是\n还是\r\n,干脆也用正则,而非split('\r')这么硬板了. 添了颜色,效果不错. Python: 效果: - 锦程网考试由试题从模拟题中批量找出答案,Python,布布扣,bubuko.com

Codeforces 48C The Race 模拟题

题目链接:点击打开链接 题意: 给定n个加油站,一辆车由A点跑到B点,每个100m有一个加油站,每开100m需要10升油. 在每个车站会检查一下油量,若车子若开不到下一个加油站则加x升油. 开始有x升油 下面给出加油的记录. 问下一次加油在哪一站.若答案唯一输出具体哪站. 油箱容量无限 思路: 水模拟.. #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h>