BOJ 2014新生暑假个人排位赛07 整合
来源:互联网 发布:单片机输出电压不恒定 编辑:程序博客网 时间:2024/05/24 05:29
A. 暑假作业题
大模拟, 字符串读入时要注意前导0
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cctype>#include <cmath>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <algorithm>#include <climits> #define MAXN 100005#define eps 1e-5#define MOD 1000000009 #define test #define For(i,m,n) for(int i=(m);i<(n);i++)#define vecfor(iter,a) for(vector<int>::iterator iter=a.begin();iter!=a.end();iter++)#define rep(i,m,n) for(int i=(m);i<=(n);i++)#define LL long long /*author birdstorm*/using namespace std;const double pi=acos(-1.0); template<class T>inline bool read(T &n){ T x = 0, tmp = 1; char c = getchar(); while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar(); if(c == EOF) return false; if(c == '-') c = getchar(), tmp = -1; while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar(); n = x*tmp; return true;} template <class T>inline void write(T n) { if(n < 0) { putchar('-'); n = -n; } int len = 0,data[20]; while(n) { data[len++] = n%10; n /= 10; } if(!len) data[len++] = 0; while(len--) putchar(data[len]+48);} int main(){ int t; LL a; char c[20]; read(t); while(t--){ scanf("%s",c); int cnt=strlen(c); bool flag1w=false, flag1e=false; bool flagb=false, flagq=false, f3=true; if(cnt==1&&c[0]=='0') printf("0"); for(int i=0; i<cnt; i++){ int p=cnt-i-1; bool flag=false; if(c[i]-'0'){ printf("%d",c[i]-'0'); flag=true; if(p>=4&&p<8) flag1w=true; if(p>=13&&p<16) flag1w=true; if(p>=8) flag1e=true; } else{ if(c[i+1]-'0'&&p>4&&p<8&&flag1w) printf("0"); else if(c[i+1]-'0'&&p>13&&p<16&&flag1w) printf("0"); else if(c[i+1]-'0'&&(p==1||p==5||p==9||p==13)) printf("0"); else if(c[i+1]-'0'&&(p==2||p==6||p==10||p==14)) printf("0"); else if(c[i+1]-'0'&&(p==3||p==7||p==11||p==15)) printf("0"); //continue; } if(p==13) flag1w=false; if(!flag){ if(flag1w&&p==4) printf("W"),flag1w=false; if(flag1e&&p==12) printf("W"),flag1w=false; if(flag1e&&p==8) printf("E"),flag1e=false; continue; } if(p==1||p==5||p==9||p==13) printf("S"); if(p==2||p==6||p==10||p==14) printf("B"); if(p==3||p==7||p==11||p==15) printf("Q"); if(p==4||p==12) printf("W"); if(p==8) printf("E"); } puts(""); } return 0;}
B. 最长数链
暴力使用dfs搜索
正确的姿势是发现数链中的数只可能是2和3的倍数, 大大降低复杂度, 可以log(n)求出
这个姿势有点慢了= =
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cctype>#include <cmath>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <algorithm>#include <climits> #define MAXN 100005#define eps 1e-5#define MOD 1000000009 #define test #define For(i,m,n) for(int i=(m);i<(n);i++)#define vecfor(iter,a) for(vector<int>::iterator iter=a.begin();iter!=a.end();iter++)#define rep(i,m,n) for(int i=(m);i<=(n);i++)#define LL long long /*author birdstorm*/using namespace std;const double pi=acos(-1.0); template<class T>inline bool read(T &n){ T x = 0, tmp = 1; char c = getchar(); while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar(); if(c == EOF) return false; if(c == '-') c = getchar(), tmp = -1; while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar(); n = x*tmp; return true;} template <class T>inline void write(T n) { if(n < 0) { putchar('-'); n = -n; } int len = 0,data[20]; while(n) { data[len++] = n%10; n /= 10; } if(!len) data[len++] = 0; while(len--) putchar(data[len]+48);} int prime[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43};int sta[MAXN],stac[MAXN];int dfs(int g,int pos,int cnt){ int ans=-1; if(g==1) return cnt; else{ For(i,pos,13){ if(g%prime[i]==0){ int len=dfs(g/prime[i],i,cnt+1); //if(len==-1) break; if(ans<=len){ ans=len; sta[cnt+1]=prime[i]; } } } } return ans;}int ans;int main(){ int a; while(read(a)){ ans=0; int t; memset(sta,0,sizeof sta); for(int i=a/2+1;i<=a;i++){ int len=dfs(i,0,0); if(len>=ans){ ans=len; For(j,0,ans+1) stac[j]=sta[j]; t=i; } } //ans=dfs(t,0,0); //For(j,0,ans+1) stac[j]=sta[j]; int g=1; printf("1"); for(int i=ans;i>=1;i--){ printf(" %d",g*stac[i]); g*=stac[i]; if(g==t) break; } puts(""); } return 0;}
C. 三角形的传说
可以证明只有三种可能解, 判断即可
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cctype>#include <cmath>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <algorithm>#include <climits> #define MAXN 100005#define eps 1e-5#define MOD 1000000009 #define test #define For(i,m,n) for(int i=(m);i<(n);i++)#define vecfor(iter,a) for(vector<int>::iterator iter=a.begin();iter!=a.end();iter++)#define rep(i,m,n) for(int i=(m);i<=(n);i++)#define LL long long /*author birdstorm*/using namespace std;const double pi=acos(-1.0); template<class T>inline bool read(T &n){ T x = 0, tmp = 1; char c = getchar(); while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar(); if(c == EOF) return false; if(c == '-') c = getchar(), tmp = -1; while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar(); n = x*tmp; return true;} template <class T>inline void write(T n) { if(n < 0) { putchar('-'); n = -n; } int len = 0,data[20]; while(n) { data[len++] = n%10; n /= 10; } if(!len) data[len++] = 0; while(len--) putchar(data[len]+48);} int main(){ int t, cs=1; int m, q; scanf("%d",&t); while(t--){ read(m),read(q); printf("Case %d: ",cs++); int ans=10000000; if(m%2==0){ if(m>=q*2){ ans=2*q+2*m; } else ans=2*q+m; } else{ if(2*q>m){ ans=2*q+m; } else ans=2*q+2*m; } if(q<=1) ans=3*m+2*q; printf("%d\n",ans); } return 0; }
D. 帮帮小叮当
dp/图论
dp的正确性: 由于是从确定状态转移至不确定状态, 所以dp的结果正确.
图论可采用SPFA, 速度也不慢.
可是使用dij+堆优化的话似乎不能在时限内通过, 原因不明
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cctype>#include <cmath>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <algorithm>#include <climits> #define MAXN 100005#define eps 1e-5#define MOD 1000000007#define INF 1000000007 #define test #define For(i,m,n) for(int i=(m);i<(n);i++)#define vecfor(iter,a) for(vector<int>::iterator iter=a.begin();iter!=a.end();iter++)#define rep(i,m,n) for(int i=(m);i<=(n);i++)#define LL long long /*author birdstorm*/using namespace std;const double pi=acos(-1.0); template<class T>inline bool read(T &n){ T x = 0, tmp = 1; char c = getchar(); while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar(); if(c == EOF) return false; if(c == '-') c = getchar(), tmp = -1; while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar(); n = x*tmp; return true;} template <class T>inline void write(T n) { if(n < 0) { putchar('-'); n = -n; } int len = 0,data[20]; while(n) { data[len++] = n%10; n /= 10; } if(!len) data[len++] = 0; while(len--) putchar(data[len]+48);} int dp[MAXN], a[MAXN];int main(){ int n, m; while(read(n)&&read(m),n||m){ For(i,0,n) read(a[i]); int ans=INF; dp[0]=a[0]-1; For(i,1,n) dp[i]=min(dp[i-1]+1,i+a[i]-1); for(int i=n-2;i>=0;i--) dp[i]=min(dp[i],dp[i+1]+1); For(i,0,n) ans=min(ans,dp[i]+n-i+m-a[i]-1); printf("%d\n",ans); } return 0;}
E. hiyot的神题
线段树维护区间gcd, 然后使用容斥原理计算答案.
考虑到1000以内的数分解素数后最多只有五个, 也可以暴力手算容斥.
比如:
LL solve(LL a, LL m){ int sz=g[a].size(); LL ret=0; if(sz==1) ret=m-m/g[a][0]; else if(sz==2) ret=m-m/g[a][0]-m/g[a][1]+m/(g[a][0]*g[a][1]); else if(sz==3){ LL a1=g[a][0], a2=g[a][1], a3=g[a][2]; ret=m-m/a1-m/a2-m/a3+m/(a1*a2)+m/(a1*a3)+m/(a2*a3)-m/(a1*a2*a3); } else if(sz==4){ LL a1=g[a][0], a2=g[a][1], a3=g[a][2], a4=g[a][3]; ret=m-m/a1-m/a2-m/a3-m/a4+m/(a1*a2)+m/(a1*a3)+m/(a1*a4)+m/(a2*a3)+m/(a2*a4)+m/(a3*a4)-m/(a1*a2*a3)-m/(a1*a2*a4)-m/(a1*a3*a4)-m/(a2*a3*a4)+m/(a1*a2*a3*a4); } else if(sz==5){ LL a1=g[a][0], a2=g[a][1], a3=g[a][2], a4=g[a][3], a5=g[a][4]; ret=m-m/a1-m/a2-m/a3-m/a4-m/a5+m/(a1*a2)+m/(a1*a3)+m/(a1*a4)+m/(a1*a5)+m/(a2*a3)+m/(a2*a4)+m/(a2*a5)+m/(a3*a4)+m/(a3*a5)+m/(a4*a5)-m/(a1*a2*a3)-m/(a1*a2*a4)-m/(a1*a2*a5)-m/(a1*a3*a4)-m/(a1*a3*a5)-m/(a1*a4*a5)-m/(a2*a3*a4)-m/(a2*a3*a5)-m/(a2*a4*a5)-m/(a3*a4*a5)+m/(a1*a2*a3*a4)+m/(a1*a2*a3*a5)+m/(a1*a2*a4*a5)+m/(a1*a3*a4*a5)+m/(a2*a3*a4*a5)-m/(a1*a2*a3*a4*a5); } return ret-1;}
这里推荐的是比较优美的dfs姿势
#include <cstdio>#include <cstring>#include <cctype>#include <cstdlib>#include <vector>#include <algorithm>#define MAXN 10005#define For(i,m,n) for(int i=(m);i<(n);i++)#define LL long long using namespace std;LL prime[]={2,3,5,7,11,13,17,19,23,29,31};struct node{ int left, right; LL gcd;}arr[MAXN<<4]; LL num[MAXN], c;LL gcd(LL a, LL b){ return b==0?a:gcd(b,a%b);}void build(int idx, int l, int r){ arr[idx].left = l, arr[idx].right = r; arr[idx].gcd = 0; if(l == r){ arr[idx].gcd = num[l]; return; } int mid = (l + r) >> 1; build(idx << 1, l, mid); build(idx << 1 | 1, mid + 1, r); arr[idx].gcd = gcd(arr[idx << 1].gcd , arr[idx << 1 | 1].gcd);}LL ans;bool query(int idx, int l, int r){ if(arr[idx].right < l||arr[idx].left > r) return false; if(arr[idx].left >= l&&arr[idx].right <= r){ ans=gcd(ans,arr[idx].gcd); return true; } query(idx << 1, l, r); query(idx << 1 | 1, l, r); return true;} void update(int idx, int val, int pos){ int l = arr[idx].left, r = arr[idx].right; if(l == r){ arr[idx].gcd=val; return; } int mid = (l + r) >> 1; if(pos <= mid) update(idx << 1, val, pos); else update(idx << 1 | 1, val, pos); arr[idx].gcd = gcd(arr[idx<<1].gcd, arr[idx<<1|1].gcd);}vector<LL> g[1111], v;void init(){ for(LL i=2; i<=1000; ++i){ g[i].clear(); LL tmp=i; For(j,0,11){ if(tmp%prime[j]==0){ while(tmp%prime[j]==0) tmp/=prime[j]; g[i].push_back(prime[j]); } } if(tmp!=1) g[i].push_back(tmp); }} LL dfs(int pos, int sz, LL a, LL m){ LL ret=0; For(i,pos,sz){ ret+=m/g[a][i]-dfs(i+1,sz,a,m/g[a][i]); } return ret;} int main(){ int t, n, q, l, r; LL g1, m; init(); while(~scanf("%d",&n)){ scanf("%lld%d",&m,&q); For(i,1,n+1) scanf("%lld",&num[i]); build(1,1,n); int o; while(q--){ scanf("%d%d",&o,&l); if(o==1){ scanf("%d",&r); ans=num[l]; query(1,l,r); if(ans==1) printf("-1\n"); else{ int sz=g[ans].size(); LL ret=m-1-dfs(0,sz,ans,m); printf("%lld\n",ret); } } else{ scanf("%lld",&g1); num[l]=g1; update(1,g1,l); } } } return 0;}
0 0
- BOJ 2014新生暑假个人排位赛07 整合
- BOJ 2014新生暑假个人排位赛03 整合
- BOJ 2014新生暑假个人排位赛04 整合
- BOJ 2014新生暑假个人排位赛05 整合
- BOJ 2014新生暑假个人排位赛06 整合
- BOJ 2014新生暑假个人排位赛08 整合
- BOJ 2014新生暑假个人排位赛09 整合
- BOJ 2014新生暑假个人排位赛11 整合
- 7.28-2014新生暑假个人排位赛07
- 2014新生暑假个人排位赛07
- 2014新生暑假个人排位赛07 A.暑假作业题
- 2014新生暑假个人排位赛07 B.最长数链
- 2014新生暑假个人排位赛07 C.三角形的传说
- BUPT2014新生暑假个人排位赛07
- BUPT 2014新生暑假个人排位赛01
- BUPT 2014新生暑假个人排位赛02
- 【总结】2014新生暑假个人排位赛03
- 【总结】2014新生暑假个人排位赛02
- Win7 加载Grub
- 单例的设计与作用
- JavaScript学习 jquery学习8 事件处理
- C语言考试
- UVALive 5033 I'm Telling the Truth
- BOJ 2014新生暑假个人排位赛07 整合
- LA 6662 —— The Last Ant(模拟)
- Hibernate对视图的映射
- 【Agile Pair Coding】Data Type Mapping
- hdoj 2087 剪花布条
- ios--UITabBarController的用法
- iocp详解
- OC 中的数组方法(不可变数组NSArray 和 可变数组 NSMutableArray)
- linux高级技巧:集群之keepalived