2017 12 10 cf 个人赛--题解 SDUT 2017 Autumn Single Contest L
来源:互联网 发布:海量数据存储算法 编辑:程序博客网 时间:2024/05/16 06:22
A:
倒着求10以下的因子
#include <iostream>#include<bits/stdc++.h>using namespace std;const int maxn = 1e5;int a[maxn],b[maxn];int factor(int n,int a[maxn],int b[maxn],int &tot){ for(int i=9;i>=2;i--) { while(n%i==0) { a[++tot] = i; n/=i; } } if(n==1) return 1; else return 0;}int qiu(long long x){ int sum = 1; while(x) { int y = x%10; x/=10; sum*=y; } return sum;}int main(){ int n; while(cin>>n) { int tot=0; if(n==0) { cout<<"10"<<endl; } else if(n<10) { cout<<n<<endl; } else { int f = factor(n,a,b,tot); if(!f) { cout<<"-1"<<endl; } else { for(int i=tot;i>=1;i--) { printf("%d",a[i]); } cout<<endl; } } } return 0;}
B:
求从s到e所用最少的钱,有三种情况的票按距离从远到近分类
输入n-1个数表示第一站到其余n-1个站的距离
#include <iostream>#include<bits/stdc++.h>#pragma g++ xxx.cc O3using namespace std;const int maxn = 555000;char a[maxn],b[maxn];int main(){ int l1,l2,l3,c1,c2,c3,n,s,e,i,A[10000],D[10000]; scanf("%d %d %d %d %d %d",&l1,&l2,&l3,&c1,&c2,&c3); //c1,c2,c3表示三种距离的票价 //l1,l2,l3表示三种收费情况的距离 scanf("%d",&n); cin>>s>>e; s--;e--; //因为前缀和,所以--,取前一位 A[0] = 0; for(int i=1;i<n;i++) { scanf("%d",&A[i]); D[i] =1000000000; } if(s>e) swap(s,e);//也有可能是返程// cout<<s<<" "<<e<<endl<<endl;// for(int i=0;i<n;i++)// cout<<A[i]<<" ";// cout<<endl; for(i=s,D[s]=0;i<=e;i++) { n = upper_bound(&A[i],&A[e]+1,A[i]+l1)-A-1; // cout<<n<<" "; D[n] = min(D[n],D[i]+c1);//更新从当前站能走到的最远的站 n = upper_bound(&A[n],&A[e]+1,A[i]+l2)-A-1; D[n] = min(D[n],D[i]+c2); // cout<<n<<" "; n = upper_bound(&A[n],&A[e]+1,A[i]+l3)-A-1; D[n] = min(D[n],D[i]+c3);// cout<<n;// cout<<endl; } cout<<D[e]<<endl; return 0;}
C:
参考博客
考虑K=L+1的情况,这种情况下先手无论拿多少个石子(1..L),都能剩下不超过L个石子让后手直接全部拿完。
如果我们构造一轮又一轮的这样的步骤,即k是L+1的倍数,那么每当先手取了s个石子,后手都能取L+1−s个石子,使得剩下的石子又变成L+1的倍数的情况,直到最后只剩L+1个石子,后手胜。
那么问题就变成了找到K的最小的大于2的因数,减一就是L了。
#include <iostream>#include <cmath>using namespace std;int main(){ int K,i,L; while (cin>>K){ for (i=3;i<=(int)sqrt(K);i++){ if (K%i==0) break; } cout<<"i "<<i<<endl; if (K%i==0) L=i-1; else if (K%2==0&&K>4) L=K/2-1; //因为去掉了因子2,所以找倍数时加上被开方漏掉的2的倍数的情况 //首先输出K%i是排除了因子2的倍数如4,8的情况,然后再特判 else L=K-1; cout<<L<<endl; } return 0;}
#include <iostream>#include <bits/stdc++.h>using namespace std;int main(){#ifndef ONLINE_JUDGE freopen("input.txt","r",stdin); freopen("output.txt","w",stdout);#endif int k; scanf("%d",&k); for(int i=3;i<=k;i++) if(k%i==0) { printf("%d",i-1); return 0; } printf("0\n"); return 0;}
D:
根据题意二分查找即可,(待+二分答案的做法)
#include <iostream>#include<bits/stdc++.h>using namespace std;struct node{ int l,r,i;}a[300000];bool operator <(node a ,node b){ if(a.l==b.l) return a.r>b.r; else return a.l<b.l;}int pan(int x,int g){ if(a[x].l<=g&&g<=a[x].r) return 1; else return 0;}int main(){ int n; cin>>n; int u,v; for(int i=1;i<=n;i++) { scanf("%d%d",&u,&v); a[i].l=u; a[i].r = v; a[i].i = i; } int m,g; cin>>m; sort(a+1,a+1+n); for(int i=1;i<=m;i++) { scanf("%d",&g); int f = 0; node uu; uu.l = g; uu.r = g; int u = upper_bound(a+1,a+1+n,uu)-a-1; //cout<<u<<" "; for(int j=u;j>=1;j--) { if(a[j].l<=g&&a[j].r>=g) { cout<<a[j].i<<endl; f = 1; break; } } if(!f)printf("-1\n"); } return 0;}
E:
tle 版
还有一个wa版利用取模暴力,不知道为什么为何一直wa
#include <iostream>#include <bits/stdc++.h>using namespace std;char s[500001],s1[250001];int main(){ int n,i; scanf("%d",&n); scanf("%s",s); scanf("%s",s1); if(strcmp(s,s1)==0) { printf("0"); } else { for( i=0;i<n;i++) { if(strcmp(s+i,s1)==0) { printf("%d",n-i); break; } s[n+i] = s[i]; s[n+i+1]='\0'; } if(n==i) { printf("-1"); } } return 0;}
裸kmp板
#include <bits/stdc++.h>using namespace std;const int maxn = 600000;char s1[maxn],s2[maxn];int Next[maxn],l1,l2;void getnext(){ int i =0 ,j = -1; Next[0] = -1; while(i<l2) { if(s2[i]==s2[j]||j==-1) { i++,j++; if(s2[i]!=s2[j]) { Next[i] = j; } else Next[i] = Next[j]; } else j = Next[j]; }}int kmp(){ int i=0,j = 0; while(i<l1&&j<l2) { if(j==-1||s1[i]==s2[j]) { i++,j++; } else j = Next[j]; } if(j>=l2)return i-l2+1; else return -1;}int main(){ int n,m; while(cin>>n) { scanf("%s%s",s1,s2); l1 = strlen(s1); l2 = strlen(s2); l1 = n*2; for(int i=0;i<n;i++) { s1[i+n] = s1[i]; } s1[l1] = 0; getnext(); int o = kmp(); if(o==-1) cout<<o<<endl; else cout<<(n-o+1)%n<<endl; } return 0;}
G:拓扑排序,一开始看错了,要验证的是上边的边不是下边的序列
#include <iostream>#include<bits/stdc++.h>using namespace std;const int maxn = 255000;int in[3000]= {0};struct node{ int x,y;} o[3100000];int tu[2000][2000]= {0},a[3000];int main(){ int n,m,u,v; cin>>n>>m; for(int i=1; i<=m; i++) { cin>>u>>v; o[i].x =u; o[i].y = v; }// for(int i=1; i<=n; i++)// {// cout<<in[i]<<" ";// // cin>>a[i];// } int y; for(int i=1; i<=n; i++) { cin>>y; a[y] = i; } int f = 1; for(int i=1; i<=m; i++) { if(a[o[i].x]>a[o[i].y]) { f = 0; break; } } if(f) printf("YES\n"); else printf("NO\n"); return 0;}
F: 字符串哈希+树状数组模版
参考博客
题意:给出一个字符串,m个操作:1,修改其中一个字符串,2,询问 [a, b] 是不是回文串。数据范围10^5。 如何快速判断字符串是不是回文串,可以用到多项式Hash。假设一个串s,那么字串s[i, j]的Hash值就是H[i, j]=s[i]+s[i+1]*x+s[i+2]*(x^2)+...+s[j]*(x^(i-j))。由于只有小写字母,因此x取27。但是H[i, j]这会很大,我们取模就可了,可以把变量类型设为unsigned long long, 那么自动溢出就相当于模2^64了。对于不同串但是Hash相同的情况,这种情况的概率是非常小的,通常可以忽略,当然我们也可以对x取多次值,求出不同情况下的Hash值。然后我们就可以用线段树或者树状数组来维护这个和了,复杂度O(nlogn)。//STATUS:C++_AC_140MS_2777KB#include <functional>#include <algorithm>#include <iostream>//#include <ext/rope>#include <fstream>#include <sstream>#include <iomanip>#include <numeric>#include <cstring>#include <cassert>#include <cstdio>#include <string>#include <vector>#include <bitset>#include <queue>#include <stack>#include <cmath>#include <ctime>#include <list>#include <set>#include <map>using namespace std;//#pragma comment(linker,"/STACK:102400000,102400000")//using namespace __gnu_cxx;//define#define pii pair<int,int>#define mem(a,b) memset(a,b,sizeof(a))#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define PI acos(-1.0)//typedeftypedef __int64 LL;typedef unsigned __int64 ULL;//constconst int N=100010;const int INF=0x3f3f3f3f;const int MOD=95041567,STA=8000010;const LL LNF=1LL<<60;const double EPS=1e-8;const double OO=1e15;const int dx[4]={-1,0,1,0};const int dy[4]={0,1,0,-1};const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};ULL bit[N],c[N][2];char s[N];int n,len;inline int lowbit(int x){ return x&(-x);}void update(int x,ULL val,int flag){ while(x<=len){ c[x][flag]+=val; x+=lowbit(x); }}ULL sum(int x,int flag){ ULL ret=0; while(x){ ret+=c[x][flag]; x-=lowbit(x); } return ret;}int main(){ // freopen("in.txt","r",stdin); int i,j,w,L,R; char op[20],ch; bit[0]=1; for(i=1;i<N;i++)bit[i]=bit[i-1]*27; while(~scanf("%s",s)) { len=strlen(s); mem(c,0); for(i=0;i<len;i++){ update(i+1,(s[i]-'a'+1)*bit[i],0); update(i+1,(s[len-i-1]-'a'+1)*bit[i],1); } scanf("%d",&n); while(n--){ scanf("%s",op); if(op[0]=='p'){ scanf("%d%d",&L,&R); ULL a=(sum(R,0)-sum(L-1,0))*bit[len-R]; ULL b=(sum(len-L+1,1)-sum(len-R,1))*bit[L-1]; if(a==b)printf("Yes\n"); else printf("No\n"); } else { scanf("%d %c",&w,&ch); update(w,(ch-s[w-1])*bit[w-1],0); update(len-w+1,(ch-s[w-1])*bit[len-w],1); s[w-1]=ch; } } } return 0;}
阅读全文
0 0
- 2017 12 10 cf 个人赛--题解 SDUT 2017 Autumn Single Contest L
- SDUT 2017 Autumn Single Contest O 周六场个人赛
- SDUT 2017 Autumn Single Contest K
- SDUT 2017 Autumn Single Contest N 模板场
- SDUT1128 Autumn Single contest
- 2016-2017 acm-icpc neerc moscow subregional contest l题题解
- SDUT 2017 个人排位赛---A
- April Fools Contest 2017 题解
- 坑爹CF April Fools Day Contest题解
- Fighting For 2017 Season Contest 1 题解
- 2017 Wuhan University Programming Contest 题解
- Nordic Collegiate Programming Contest 2017 题解
- ZJOI2017 Training Contest 12题解
- SDKD 2016 Summer Single Contest #12 .B
- SDKD 2016 Summer Single Contest #12 .D
- SDKD 2016 Summer Single Contest #12 .F
- SDKD 2016 Summer Single Contest #12 .G
- SDUT - 2017年寒假集训 阶段测试赛3(个人) -- 解题报告
- javascript获取项目根目录带项目名
- 13-CSS3提高
- 在C/C++语言中使用正则表达式
- 【模板】树状数组的区间加值和区间查询
- 求两个正整数均值(防溢出)
- 2017 12 10 cf 个人赛--题解 SDUT 2017 Autumn Single Contest L
- 最好用的 IntelliJ 插件 Top 10
- 漫画:什么是 volatile 关键字?
- 深度学习(十一)——Winograd(1)
- 8086汇编语言程序设计
- 国务院为何力推公共资源配置领域政府信息公开?
- SparkStreaming计算WordCount简单示例
- 35 个 Java 代码性能优化总结
- Linux的一些指令概念(简单)