6.29考试

幸运数字(number)
Time Limit:1000ms Memory Limit:64MB
题目描述
LYK 最近运气很差,例如在 NOIP 初赛中仅仅考了 90 分,刚刚卡进复赛,于是它决定使
用一些方法来增加自己的运气值。
它觉得,通过收集幸运数字可以快速的增加它的 RP 值。
它给幸运数字下了一个定义: 如果一个数 x 能被 3 整除或被 5 整除或被 7 整除, 则这个
数为幸运数字。
于是它想让你帮帮它在 L~R 中存在多少幸运数字。
输入格式(number.in)
第一行两个数 L,R。
输出格式(number.out)
一个数表示答案。
输入样例
10 15
输出样例
4
数据范围
对于 50%的数据 $1\leq L\leq R\leq 10^5$。
对于 60%的数据 $1\leq L\leq R\leq 10^9$。
对于 80%的数据 $1\leq L\leq R\leq 10^{18}$。
对于 90%的数据 $1\leq L\leq R\leq 10^{100}$。
对于另外 10%的数据 $L=1,1\leq R\leq 10^{100}$。
对于 100%的数据 L,R 没有前导 0。

思路分析:

数论太弱了,容斥原理都不会。。。

简单说一下容斥原理,用的最多的是三集合容斥原理。公式:

$\left|A\cup B\cup C\right| = \left|A\right| + \left|B\right| + \left|C\right| - \left|A\cap B\right| - \left|B\cap C\right| - \left|C\cap A\right| + \left|A\cap B\cap C\right|$

然后就是一顿套公式啊。

看到前导0,$10^{100}$高精的节奏啊。一顿套高精...

OMG,还是80分弃疗吧,毕竟太弱了。

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <iostream>
 5 #include <algorithm>
 6 #include <string>
 7 #include <cstring>
 8 using namespace std;
 9 //int L,R;
10 //int work(int x,int y) {return x/y;}
11 char s1[1005],s2[1005];
12 int S1[1005],S2[1005],len1,len2,s[1005],S[1005],i;
13 void pl(int *a,int *b)
14 {
15     for (int i=a[0]+1; i<=b[0]; i++) a[i]=0;
16     for (int i=1; i<=b[0]; i++) a[i]+=b[i];
17     a[0]=max(a[0],b[0]);
18     for (int i=1; i<a[0]; i++) if (a[i]>=10) {a[i+1]++; a[i]-=10;}
19     if (a[a[0]]>=10) {a[a[0]+1]=1; a[a[0]]-=10; a[0]++;}
20 }
21 void mn(int *a,int *b)
22 {
23     for (int i=a[0]+1; i<=b[0]; i++) a[i]=0;
24     for (int i=1; i<=b[0]; i++) a[i]-=b[i];
25     for (int i=1; i<a[0]; i++)
26     if (a[i]<0) {a[i]+=10; a[i+1]--;}
27     while (a[0]>1 && a[a[0]]==0) a[0]--;
28 }
29 void work(int *a,int b,int *c)
30 {
31     for (int i=1; i<=a[0]; i++) c[i]=a[i];
32     for (int i=a[0]; i>=1; i--)
33     {
34         c[i-1]+=c[i]%b*10;
35         c[i]/=b;
36     }
37     c[0]=a[0];
38     while (c[0]>1 && c[c[0]]==0) c[0]--;
39 }
40 int main()
41 {
42     cin>>L>>R;
43     cout<<work(R,3)+work(R,5)+work(R,7)-work(R,15)-work(R,21)-work(R,35)+work(R,105)-
44           work(L-1,3)-work(L-1,5)-work(L-1,7)+work(L-1,15)+work(L-1,21)+work(L-1,35)-work(L-1,105);
45     return 0;
46     freopen("number.in","r",stdin);
47     freopen("number.out","w",stdout);
48     scanf("%s",s1);
49     scanf("%s",s2);
50     len1=strlen(s1);
51     len2=strlen(s2);
52     for (i=1; i<=len1; i++) S1[len1-i+1]=s1[i-1]-'0';
53     S1[0]=len1;
54     for (i=1; i<=len2; i++) S2[len2-i+1]=s2[i-1]-'0';
55     S2[0]=len2;
56     work(S2,3,s);
57     work(S2,5,S);
58     pl(s,S);
59     work(S2,7,S);
60     pl(s,S);
61     work(S2,15,S);
62     mn(s,S);
63     work(S2,21,S);
64     mn(s,S);
65     work(S2,35,S);
66     mn(s,S);
67     work(S2,105,S);
68     pl(s,S);
69     S[0]=1; S[1]=1;
70     mn(S1,S);
71     work(S1,15,S);
72     pl(s,S);
73     work(S1,21,S);
74     pl(s,S);
75     work(S1,35,S);
76     pl(s,S);
77     work(S1,3,S);
78     mn(s,S);
79     work(S1,5,S);
80     mn(s,S);
81     work(S1,7,S);
82     mn(s,S);
83     work(S1,105,S);
84     mn(s,S);
85     for (i=s[0]; i>=1; i--) cout<<s[i];
86     return 0;
87 }
丧心病狂...

蚂蚁运输(ant)
Time Limit:5000ms Memory Limit:64MB
题目描述
LYK 在观察一些蚂蚁。
蚂蚁想要积攒一些货物来过冬。积攒货物的方法是这样的。
对于第i只蚂蚁, 它要从li出发, 拿起货物, 走到ri处放下货物, 需要消耗的时间为|ri-li|。
而且所有蚂蚁都是可以同时进行的,也就是说,假如有 m 只蚂蚁,那么运输完货物的时间
为 max{|ri-li|}。
LYK 决定帮蚂蚁一把,它发明了空间传输装置。具体地,当蚂蚁走到 X 处时,它可以不
耗费任意时间的情况下瞬间到达 Y,或者从 Y 到达 X。也就是说,一个蚂蚁如果使用了空间
传输装置,它耗费的时间将会是 min{|li-X|+|ri-Y|,|li-Y|+|ri-X|},当然蚂蚁也可以选择徒步走
到目标点。
由于空间传输装置非常昂贵,LYK 打算只建造这么一台机器。并且 LYK 想让蚂蚁运输完
货物的时间尽可能短,你能帮帮它吗?
输入格式(ant.in)
第一行两个数 n,m,n 表示 li,ri 的最大值。
接下来 m 行,每行两个数 li,ri。
输出格式(ant.out)
一个数表示答案
输入样例
5 2
1 3
2 4
输出样例
1
数据范围
对于 20%的数据 n,m<=100。
对于 40%的数据 n,m<=1000。
对于 60%的数据 n<=100000,m<=1000。
对于 80%的数据 n,m<=100000。
对于 100%的数据 n,m<=1000000,1<=li,ri<=n(li=ri 时你甚至可以无视这只蚂蚁) 。
样例解释
令空间传输装置的参数中 X=2,Y=3 或者 X=3,Y=2 都行。

思路分析:

今天唯一一道比较可做的题目。

大概是二分答案。

xxy讲了大概1h左右的二分答案,感觉听懂了些。

定义答案区间为[0,1000000].

路径是无向的.....将所有路线转化为一个方向.

然后开始二分答案,推出式子来一顿套模板...

//以下为题解:

观察到答案具有可二分性。我们可以二分答案。
由于路径都是无向的,因此对于任意一条方案li,ri若li>ri则可以交换li和ri。
我们设二分的答案为x。
对于那些li+x>=ri的方案我们直接默认为可行。
我们规定X<=Y。
对于li+x<ri的方案。只有一种可能能够完成,即,从li出发,到达X,到达Y,到达ri。
也就是说,如果X确定,Y存在于一段区间内。
我们来看li>=X的情况。
先求出X=n时符合条件的Y的区间。当X慢慢减少时,这个区间肯定也在慢慢合拢,并且满足li>=X的条件也会越来越多。我们可以线性求出所有这个区间。
对于li<X的情况也同理。
这样就能做到线性判断,总复杂度nlgn。(这里默认n与m同阶)

数学神坑题啊...表示呵呵.

End.

转载于:https://www.cnblogs.com/TheRoadToAu/p/7096595.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值