2017 12 10 cf 个人赛--题解 SDUT 2017 Autumn Single Contest L
2017-12-12 17:03
483 查看
A:
倒着求10以下的因子
B:
求从s到e所用最少的钱,有三种情况的票按距离从远到近分类
输入n-1个数表示第一站到其余n-1个站的距离
C:
参考博客
考虑K=L+1的情况,这种情况下先手无论拿多少个石子(1..L),都能剩下不超过L个石子让后手直接全部拿完。
如果我们构造一轮又一轮的这样的步骤,即k是L+1的倍数,那么每当先手取了s个石子,后手都能取L+1−s个石子,使得剩下的石子又变成L+1的倍数的情况,直到最后只剩L+1个石子,后手胜。
那么问题就变成了找到K的最小的大于2的因数,减一就是L了。
D:
根据题意二分查找即可,(待+二分答案的做法)
E:
tle 版
还有一个wa版利用取模暴力,不知道为什么为何一直wa
裸kmp板
G:拓扑排序,一开始看错了,要验证的是上边的边不是下边的序列
F: 字符串哈希+树状数组模版
参考博客
倒着求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 O3 using 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 = min(D ,D[i]+c1);//更新从当前站能走到的最远的站 n = upper_bound(&A ,&A[e]+1,A[i]+l2)-A-1; D = min(D ,D[i]+c2); // cout<<n<<" "; n = upper_bound(&A ,&A[e]+1,A[i]+l3)-A-1; D = min(D ,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) //typedef typedef __int64 LL; typedef unsigned __int64 ULL; //const const 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 ,c [2]; char s ; 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; }
相关文章推荐
- SDUT 2017 Autumn Single Contest O 周六场个人赛
- SDUT 2017 Autumn Single Contest N 模板场
- SDUT 2017 Autumn Single Contest K
- SDUT 2017 Autumn Single Contest K
- 20171116SDUTAutumn Single Contest
- SDUT1128 Autumn Single contest
- 2017 Multi-University Training Contest 10 && HDU 6178 Monkeys 【贪心||树形DP】
- 2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 2) 题解
- (2017)第八届蓝桥杯大赛个人赛省赛(软件类) C/C++ 大学A组 题解(第一题和第二题)
- 题解___CodeForces 558A___2015_10_个人赛_1001
- 2017 Multi-University Training Contest 10 1011 Two Paths HDU 6181 (次短路+最短路数量)
- 2017 Multi-University Training Contest 10 1001 Admiral HDU 6171 (双向搜索 哈希)
- 2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) 【solved:9 / 12】
- April Fools Contest 2018[cf 愚人节专场题解]
- April Fools Contest 2017 题解
- (2017)第八届蓝桥杯大赛个人赛省赛(软件类) C/C++ 大学A组 题解(第九题)
- 2017 Multi-University Training Contest - Team 10
- 2017 Multi-University Training Contest - Team 10
- HDU 6172 Array Challenge(打表+矩阵快速幂)——2017 Multi-University Training Contest - Team 10
- 2017 Multi-University Training Contest - Team 1 (5/12)