第三周 7.25 --- 7.31

新的一周...>_<

7.25

hdu 5750  Dertouzos

定义 d 为 一个数的最大的除它本身的约数,给出 n,D,问小于 n 的数里有多少个数的d 为 D

比赛的时候 只想到 去 算 比d的最小质因数还小的素数的个数

还有 一个数的范围的条件,x <= (n-1)/d

所以 x 的范围 是 min(md[d],(n-1)/d)

还有没想到 的是 分一下 d 是大数还是 小数的情况

然后...就自信满满地...既没有用upper_bound 去找个数 还用了个挫挫的筛 ,还每次找最小质因数的时候去筛一次...

F5了三次还在running 就知道 T掉了 ...TWT

T的就是我这样的sb..

抄了 一神 的筛..orz

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cstdio>
 5 using namespace std;
 6 const int maxn = 1e7+5;
 7 int n,d,pr[maxn],md[maxn];
 8 
 9 void GetPrime(){
10     for(int i = 2;i < maxn;i++){
11         if(!pr[i]) pr[++pr[0]] = i,md[i] = i;
12         for(int j = 1;j <= pr[0] && pr[j]*i < maxn;j++){
13             pr[i*pr[j]] = 1;
14             md[i*pr[j]] = pr[j];
15             if(i % pr[j] == 0) break;
16         }
17     }
18 }
19 
20 void solve(){
21     int ans = 0;
22     if(d <= maxn) ans = upper_bound(pr+1,pr+pr[0]+1,min((n-1)/d,md[d])) -pr-1;
23     else{
24         for(int i = 1;pr[i] <= (n-1)/d && i <= pr[0];i++){
25             ans = i;
26             if(d%pr[i] == 0) break;
27         }
28     }
29     printf("%d\n",ans);
30 }
31 
32 int main(){
33     GetPrime();
34     int T;
35     scanf("%d",&T);
36     while(T--){
37         scanf("%d %d",&n,&d);
38         solve();
39     }
40     return 0;
41 }
View Code

 

cf 364div2 c They Are Everywhere

给一排字母,问能够覆盖到每种字母的最短区间是多长

第一反应是枚举左端点,二分右端点,维护一个最大值..

还是不会写二分...一直 wa ,差点错过早上的公交车..sigh

一神教第二遍..我太笨了

确定端点的时候,看左边可行,还是右边可行,

如果 是 右边可行的话,l = mid+1

如果是左边可行的话,l = mid

可行的点,不要动他 !!!!!

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <set>
 6 using namespace std;
 7 const int maxn = 1e5+5;
 8 char s[maxn];
 9 int a[maxn][55],n,m;
10 
11 int id (char x){
12     int num = 0;
13     if(x >= 'A' && x <= 'Z') return x-'A';
14     if(x >= 'a' && x <= 'z') return x-'a'+26;
15 }
16 
17 int ok(int l,int r){
18     int cnt = 0;
19     for(int i = 0;i <= 51;i++){
20         int tmp = a[r][i] - a[l-1][i];
21         if(tmp != 0){
22             cnt++;
23         }
24     }
25     return cnt;
26 }
27 
28 void solve(){
29     memset(a,0,sizeof(a));
30     set<char> S;
31     for(int i = 1;i <= n;i++){
32         for(int j = 0;j <= 51;j++) a[i][j] = a[i-1][j];
33         a[i][id(s[i])] = a[i-1][id(s[i])]+1;
34         S.insert(s[i]);
35     }
36     m = S.size();
37     int ans = n+1;
38     int lb,ub,mid;
39     for(int i = 1;i <= n;i++){
40         lb = i,ub = n;
41         if(ok(lb,ub) < m) continue;
42         while(lb < ub){
43             mid = lb+(ub-lb)/2;
44             if(ok(i,mid) < m) lb = mid+1;
45             else ub = mid;
46             //printf("i = %d lb = %d ub = %d mid = %d\n",i,lb,ub,mid);
47         }
48         //printf("------ i = %d lb = %d ub = %d\n",i,lb,ub);
49         if(ok(i,lb) == m){
50         //    printf("====ok(%d,%d) = %d\n",i,lb,ok(i,lb));
51             ans = min(ans,lb-i+1);
52         }
53         if(ok(i,ub) == m){
54         //    printf("================ok(%d,%d) = %d\n",i,ub,ok(i,ub));
55             ans = min(ans,ub-i+1);
56         }
57     }
58     printf("%d\n",ans);
59 }
60 
61 int main(){
62     while(scanf("%d",&n) != EOF){
63         scanf("%s",s+1);
64         solve();
65     }
66     return 0;
67 }
View Code

 7.26

多校懵逼

7.27

不懂搞死小圆

 

7.28

多校懵逼

cf 269B - Greenhouse Effect

n 棵植物共m种,和它们的坐标,每次操作可以将一盆植物挪到任意位置,求将m种植物挪成1 2 3 ... m 这样排列的至少需要挪多少次

和上周的bc的第二题一样,求出以 a[i] 为结尾的LIS ,扫一遍求个最小值

上周bc 是抄的板,这个是自己写的了

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 const int maxn = 1e5+5;
 7 int a[maxn],b[maxn],c[maxn],n,m;
 8 int dp[maxn];
 9 
10 int lowbit(int x){return x & (-x);}
11 
12 int query(int x){
13     int ret = 0;
14     while(x){
15         ret = max(ret,c[x]);
16         x -= lowbit(x);
17     }
18     return ret;
19 }
20 
21 void update(int x,int d){
22     while(x < maxn){
23         c[x] = max(c[x],d);
24         x += lowbit(x);
25     }
26 }
27 
28 void solve(){
29     memset(dp,0,sizeof(dp));
30     for(int i = 1;i <= n;i++){
31         dp[i] = query(a[i])+1;
32         update(a[i],dp[i]);
33     }
34     //for(int i = 1;i <= n;i++) printf("%d ",dp[i]);
35     //printf("\n");
36     int ans = n+1;
37     for(int i = 1;i <= n;i++) ans = min(ans,n-dp[i]);
38     printf("%d\n",ans);
39 }
40 
41 int main(){
42     while(scanf("%d %d",&n,&m) != EOF){
43         double x;
44         for(int i = 1;i <= n;i++) scanf("%d %lf",&a[i],&x);
45         memset(c,0,sizeof(c));
46         solve();
47     }
48     return 0;
49 }
View Code

 

7.29

还是不懂搞死小圆

不懂bonds

 

7.30

写了个点双缩点再求 LCA wa了一天...开始怀疑狗生

司老大曰:这不是很正常的嘛

实习受挫..

司老大曰:多学点东西不挺好吗,慢慢来

谨记司老大教诲>_<

 

其实我是有做bc 的TwT,先看的1002, 想到的时候 1002的时候 都过了300人了,就没打了..

接着看1003..没有想到 把 y 拆成 y = z*z 这个形式,瞎打表找规律半天 GG了

hdu 5776 sum

给出一个序列,问是否存在连续一段子序列的和是m的倍数

如果 m <= n 肯定是可以的,如果 m > n 就看一个余数是不是出现了两次,如果出现了两次,这一段的和就一定能整除m

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 const int maxn = 1e5+5;
 7 int n,m,vis[maxn],a[maxn];
 8 
 9 void solve(){
10     memset(vis,0,sizeof(vis));
11     if(m <= n){
12         puts("YES");
13         return;
14     }
15     memset(vis,0,sizeof(vis));
16     int sum = 0;
17     for(int i = 1;i <= n;i++){
18         sum += a[i];
19         sum = sum%m;
20         if(vis[sum] || sum == 0){
21             puts("YES");
22             return;
23         }
24         vis[sum] = 1;
25     }
26     puts("NO");
27 }
28 
29 int main(){
30     int T;
31     scanf("%d",&T);
32     while(T--){
33         scanf("%d %d",&n,&m);
34         for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
35         solve();
36     }
37     return 0;
38 }
View Code

 

hdu 5777 domino

n 个骨牌,高度可以自己任意定,但是至少高为 1,相邻两个骨牌的距离为 di
可以推k次,可以选择往左或者往右推,碰倒相邻 的条件是高度至少为di+1,问推倒所有骨牌的骨牌高度和最少是多少

如果 k = n 的话,就分别推倒每个就好了

如果 k = n-1的话,就去找一个 d 最小的来被推倒..

...所以sort 一下找 n-k就可以了

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef long long LL;
 7 const int maxn = 1e5+5;
 8 int n,k,a[maxn];
 9 typedef long long LL;
10 
11 void solve(){
12     sort(a+1,a+n);
13     LL ans = 1LL*n;
14     for(int i = 1;i <= n-k;i++) ans += a[i];
15     printf("%I64d\n",ans);
16 }
17 
18 int main(){
19     int T;
20     scanf("%d",&T);
21     while(T--){
22         scanf("%d %d",&n,&k);
23         for(int i = 1;i <= n-1;i++) scanf("%d",&a[i]);
24         solve();
25     }
26     return 0;
27 }
View Code

 

hdu 5778 abs

给出 x ,要找出 这样 的 y ,使得abs(y-x)最小
y >= 2
y的所有质因数的个数都为 2

拆成 y = z*z 的形式...这样就判断 z 的每个质因数 是不是 只出现了一次

没想到...我好菜啊..

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <algorithm>
 6 using namespace std;
 7 typedef long long LL;
 8 LL n,sq;
 9 
10 bool check(LL y){
11     int cnt;
12     for(LL j = 2;1LL*j*j <= y;j++){
13         if(y%j == 0){
14             cnt = 0;
15             while(y%j == 0){
16                 cnt++;
17                 y = y/j;
18                 if(cnt > 1) return false;
19             }
20         }
21     }
22     cnt = 0;
23     if(y > 1) cnt++;
24     return true;
25 }
26 
27 LL ok(int x){
28     for(LL i = sq+x;;i = i+x){
29         if(check(i)){
30             return abs(n-i*i);
31         }
32     }
33 }
34 
35 void solve(){
36     if(n <= 4){
37         printf("%I64d\n",4-n);
38         return;
39     }
40     sq = sqrt(n);
41     LL ans = 1LL << 60;
42     if(check(sq)){
43         ans = min(ans,abs(n-sq*sq));
44         //printf("ans1 = %I64d\n",ans);
45     }
46     ans = min(ans,ok(1));
47     //printf("ans2 = %I64d\n",ans);
48     ans = min(ans,ok(-1));
49     //printf("ans3 = %I64d\n",ans);
50     printf("%I64d\n",ans);
51 }
52 
53 int main(){
54     int T;
55     scanf("%d",&T);
56     while(T--){
57         scanf("%I64d",&n);
58         solve();
59     }
60     return 0;
61 }
View Code

 

转载于:https://www.cnblogs.com/wuyuewoniu/p/5705525.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值