{purple8}
##二分查找##
很久之前做过的Huffman编码,用优先队列
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 6 using namespace std; 7 8 const int lenth=300; 9 int main() 10 { 11 char str[10010]; 12 while(scanf("%s",str)) 13 { 14 if(strcmp(str,"END")==0) break; 15 int len=strlen(str); 16 int worse=len<<3;//固定长度编码所需的总位数 17 char ch[lenth]; 18 int lench=0;//输入字符的总类 19 int i,j,num[lenth];//对应每种字符的数目,无需关注具体对应哪个字符 20 memset(num,0,lenth); 21 22 for(i=0;i<len;i++) 23 { 24 for(j=0;j<lench;j++) //注意 25 if(str[i]==ch[j]) {num[j]++;break;} 26 if(j==lench) 27 { 28 ch[j]=str[i]; 29 num[j]++; 30 lench++; 31 } 32 } 33 34 priority_queue<int,vector<int>,greater<int> > pq; 35 for(int i=0;i<lench;i++) pq.push(num[i]); 36 int sum=0; 37 while(true) 38 { 39 int aa=pq.top(); 40 pq.pop(); 41 if(pq.empty()){ 42 if(lench==1) sum=aa; 43 break; 44 } 45 int bb=pq.top(); 46 pq.pop(); 47 sum+=aa+bb; 48 pq.push(aa+bb); 49 50 } 51 printf("%d %d %.1lf\n",worse,sum,worse*1.0/sum); 52 } 53 return 0; 54 }
好像又回到最开始只会看题解的时候了-_-||
1 #include<cstdio> 2 #include<iostream> 3 #include<sstream> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn=10005; 8 int a[maxn]; 9 int n; 10 11 void flip(int p){ 12 for(int i=0;i<p-i;i++) swap(a[i],a[p-i]); 13 14 printf("%d ",n-p); 15 } 16 17 18 19 int main(){ 20 string s; 21 while(getline(cin,s)){ 22 cout<<s<<"\n"; 23 stringstream ss(s) ; 24 n=0; 25 while(ss>>a[n]) n++; 26 27 for(int i=n-1;i>0;i--){ 28 int p=max_element(a,a+i+1)-a;//找到最大的数的下标 29 30 if(p==i) continue;//如果这块饼的位置是对的,就不管 31 if(p>0) flip(p);//如果饼不是在0位置,那么将这块饼 翻到0位置 32 flip(i);//将这块 饼翻到它应该在的位置 33 } 34 printf("0\n"); 35 } 36 return 0; 37 }
数形结合,半年前费多大劲也没看很明白。。。
这次虽然理解了但还是写不出来,代码能力还是很弱=_=||
参考:http://blog.csdn.net/LsFlyt/article/details/50682786
1 #include <cstdio> 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 int T; 6 int n,L; 7 int s[100050]; 8 int q[100050]; 9 int l,r; 10 int ansl,ansr; 11 char op; 12 int now; 13 14 int cross(int a,int b,int c,int d) 15 { 16 //x1*y2-x2*y1<0时line1在line2左边!!!说明line1的斜率更大一些 17 return (b-a)*(s[d]-s[c])-(d-c)*(s[b]-s[a]); 18 } 19 20 int main() 21 { 22 scanf("%d",&T); 23 while (T--) 24 { 25 scanf("%d%d",&n,&L); 26 getchar(); 27 s[0]=0; 28 for (int i=1;i<=n;i++) 29 { 30 op=getchar(); 31 s[i]=op-'0'+s[i-1]; 32 } 33 l=1; 34 r=0; 35 ansl=0; 36 ansr=L; 37 for (int i=L;i<=n;i++) //枚举右端点 38 { 39 now=i-L; //左端点 40 while (l<r && cross(q[r-1],q[r],q[r],now)<=0) //删去最右边的不满足下凸的点 41 { 42 r--; 43 } 44 r++; 45 q[r]=now; 46 47 while (l<r && cross(q[l+1],i,q[l],i)<=0) //求得当前最大斜率,并删去左边用不到的点 48 { 49 l++; 50 } 51 52 if (cross(q[l],i,ansl,ansr)<0 || (cross(q[l],i,ansl,ansr)==0 && ansr-ansl>i-q[l])) //更新答案 53 { 54 ansl=q[l]; 55 ansr=i; 56 } 57 } 58 59 ansl++; 60 printf("%d %d\n",ansl,ansr); 61 } 62 63 return 0; 64 }
二分,一点细节没注意到又坑了好久。。。
1 #include <cstdio> 2 #include <bits/stdc++.h> 3 using namespace std; 4 #define LL long long 5 const int maxn=520; 6 int a[maxn]; 7 int vis[maxn]; 8 int n,k; //n个整数,分层k段 9 bool p(LL x) 10 { 11 int i=0; 12 int cnt=0; 13 while(i>=0){ 14 LL temp=0; 15 while(i>=0&&temp+a[i]<=x) {temp+=a[i];i--;} 16 cnt++; 17 } 18 return cnt<=k; 19 } 20 int main() 21 { 22 int t; 23 scanf("%d",&t); 24 while(t--) 25 { 26 int v=0; 27 LL sum=0; 28 memset(vis,0,sizeof(vis)); 29 scanf("%d%d",&n,&k); 30 for(int i=0;i<n;i++) { 31 scanf("%d",&a[i]); 32 v=max(v,a[i]); 33 sum+=a[i]; 34 } 35 LL l=v,r=sum; 36 37 while(l<=r) 38 { 39 LL m=l+(r-l)/2; 40 if(p(m)) r=m-1; 41 else l=m+1; 42 } 43 // printf("%d\n",l); 44 int ct=0; 45 int i=n-1; 46 while(i>=0) { 47 LL temp=0; 48 ct++; 49 while(i>=0&&temp+a[i]<=l) { 50 if(i+1==k-ct) break; //如果剩下的数字刚好等于还需要分的组数,在这WA了n次 51 temp+=a[i]; 52 i--; 53 } 54 if(i+1==k-ct) { 55 for(int j=0;j<=i;j++) vis[j]=1; //每个分一组即可 56 break; 57 } 58 if(i>=0) vis[i]=1; 59 } 60 for(int j=0;j<n-1;j++) 61 { 62 printf("%d ",a[j]); 63 if(vis[j]) printf("/ "); 64 } 65 printf("%d\n",a[n-1]); 66 } 67 }
Huffman编码,优先队列n-1次操作。
1 #include <cstdio> 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 int n; 6 int x; 7 int main() 8 { 9 while(scanf("%d",&n)&&n) 10 { 11 priority_queue <int, vector<int> ,greater<int> > pq; 12 for(int i=0;i<n;i++) 13 { 14 scanf("%d",&x); 15 pq.push(x); 16 } 17 int ans=0; 18 for(int i=0;i<n-1;i++) 19 { 20 int a=pq.top();pq.pop(); 21 int b=pq.top();pq.pop(); 22 ans+=a+b; 23 pq.push(a+b); 24 } 25 printf("%d\n",ans); 26 } 27 }
递归求解,感觉lrj的不太好理解。。。
1 #include <cstdio> 2 #include <bits/stdc++.h> 3 using namespace std; 4 #define LL long long 5 6 LL g(int k,int i) 7 { 8 if(k==0) if(i>=1) return 1; 9 else return 0; 10 if(i>=1<<(k-1)) 11 { 12 LL c=pow(3,k-1); 13 return 2*g(k-1,i-(1<<(k-1)))+c; 14 } 15 else return g(k-1,i); 16 } 17 18 int main() 19 { 20 int t; 21 int kase=0; 22 scanf("%d",&t); 23 while(t--) 24 { 25 int k,a,b; 26 scanf("%d%d%d",&k,&a,&b); 27 LL temp=1<<k; 28 LL x=g(k,temp-a+1); 29 LL y=g(k,temp-b); 30 printf("Case %d: %lld\n",++kase,x-y); 31 } 32 }
1 #include <cstdio> 2 #include <bits/stdc++.h> 3 using namespace std; 4 #define LL long long 5 6 LL g(int k,int i) 7 { 8 if(k==0) if(i<=1) return 1; 9 else return 0; 10 if(i<=1<<(k-1)) 11 { 12 LL c=pow(3,k-1); 13 return 2*g(k-1,i)+c; 14 } 15 else return g(k-1,i-(1<<k-1)); 16 } 17 18 int main() 19 { 20 int t; 21 int kase=0; 22 scanf("%d",&t); 23 while(t--) 24 { 25 int k,a,b; 26 scanf("%d%d%d",&k,&a,&b); 27 LL temp=1<<k; 28 LL x=g(k,a); 29 LL y=g(k,b+1); 30 printf("Case %d: %lld\n",++kase,x-y); 31 } 32 }
读错题了,WA好久=_=||
1 #include <cstdio> 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int maxn=100010; 5 6 int p[maxn],q[maxn]; 7 int n; 8 9 int main() 10 { 11 int t; 12 int kase=0; 13 scanf("%d",&t); 14 while(t--) 15 { 16 scanf("%d",&n); 17 int ans=-1; 18 for(int i=0;i<n;i++) scanf("%d",&p[i]); 19 for(int i=0;i<n;i++) scanf("%d",&q[i]); 20 int ok=1; 21 int i=0; 22 for(int i=0;i<n;i++) 23 { 24 ok=1; 25 int temp=0; 26 int cur; 27 for(int j=0;j<n;j++) 28 { 29 cur=(i+j)%n; 30 temp=temp+p[cur]-q[cur]; 31 if(temp<0) {ok=0;break;} 32 } 33 if(ok) {ans=i+1;break;} 34 if(cur<i||(cur+1)%n==i) break; 35 i=cur; 36 } 37 if(ans!=-1) printf("Case %d: Possible from station %d\n",++kase,ans); 38 else printf("Case %d: Not possible\n",++kase); 39 } 40 41 }
与非门电路
这个真的看不懂了,,过一阵再回来做吧。p246 题解:http://blog.csdn.net/u014569598/article/details/38875187
1 #include <cstdio> 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 const int maxm=200000+5; 6 int n,m; 7 8 struct node 9 { 10 int a,b,w; 11 }q[maxm]; 12 13 int print(int k) 14 { 15 for(int i=1;i<=m;i++) 16 { 17 int x=q[i].a; 18 int y=q[i].b; 19 int va=x<0?-x>k:q[x].w; 20 int vb=y<0?-y>k:q[y].w; 21 q[i].w=!(va&&vb); 22 } 23 return q[m].w; 24 } 25 int solve(int vn) 26 { 27 int l=1,r=n; 28 while(l<=r) 29 { 30 int mid=l+(r-l)/2; 31 if(print(mid)==vn)r=mid-1; 32 else l=mid+1; 33 } 34 return l; 35 } 36 int main() 37 { 38 int T; 39 scanf("%d",&T); 40 while(T--) 41 { 42 scanf("%d%d",&n,&m); 43 for(int i=1;i<=m;i++) 44 scanf("%d%d",&q[i].a,&q[i].b); 45 int v0=print(0); 46 int vn=print(n); 47 if(v0==vn) 48 { 49 for(int i=1;i<=n;i++)printf("0"); 50 } 51 else 52 { 53 int x=solve(vn); 54 for(int i=1;i<x;i++)printf("0"); 55 printf("x"); 56 for(int i=x+1;i<=n;i++)printf("1"); 57 } 58 printf("\n"); 59 } 60 return 0; 61 }
方法一:滑动窗口,相对好理解一些。
1 #include<cstdio> 2 #include<cstring> 3 #define M(a) memset(a,0,sizeof(a)) 4 int a[500010],s,n,cnt[500010]; 5 bool ok[500010]; 6 int main() 7 { 8 int i,j,k,m,x,y,z,p,q,T,ans,tot; 9 bool b; 10 scanf("%d",&T); 11 while (T--) 12 { 13 M(a); 14 scanf("%d%d",&s,&n); 15 for (i=1;i<=n;i++) 16 scanf("%d",&a[i+s]); 17 tot=0; 18 M(cnt); 19 M(ok); 20 for (i=2;i<=s+n;i++) 21 { 22 if (a[i-1]) 23 { 24 cnt[a[i-1]]--; 25 if (cnt[a[i-1]]==1) tot--; 26 } 27 if (a[i+s-1]) 28 { 29 cnt[a[i+s-1]]++; 30 if (cnt[a[i+s-1]]==2) tot++; 31 } 32 ok[i]=!tot; 33 } 34 ans=0; 35 for (i=2;i<=s+1;i++) 36 { 37 b=1; 38 for (j=i;j<=n+s;j+=s) 39 if (!ok[j]) 40 { 41 b=0; 42 break; 43 } 44 if (b) ans++; 45 } 46 printf("%d\n",ans); 47 } 48 }
方法二:排除掉不可能的,剩下的就是可能的情况,有一点细节暂时理解不了
1 #include<cstdio> 2 #include<cstring> 3 #define M(a) memset(a,0,sizeof(a)) 4 int fir[100010],ne[100010],a[100010]; 5 bool b[100010]; 6 int main() 7 { 8 int i,j,k,m,n,p,q,x,y,z,T,tot,ans,s,l,r; 9 scanf("%d",&T); 10 while (T--) 11 { 12 M(fir); 13 M(ne); 14 M(a); 15 memset(b,1,sizeof(b)); 16 scanf("%d%d",&s,&n); 17 for (i=1;i<=n;i++) 18 scanf("%d",&a[i]); 19 for (i=n;i>=1;i--) 20 { 21 ne[i]=fir[a[i]]; 22 fir[a[i]]=i; 23 } 24 for (k=1;k<=s;k++) 25 { 26 for (i=fir[k];ne[i];i=ne[i]) 27 { 28 if (ne[i]-i>=s) continue; 29 l=i%s; 30 r=(ne[i]%s-1+s)%s; 31 if (l<=r) 32 { 33 for (j=0;j<l;j++) b[j]=0; 34 for (j=r+1;j<s;j++) b[j]=0; 35 } 36 else 37 for (j=r+1;j<l;j++) b[j]=0; //无法理解!!! 38 } 39 } 40 ans=0; 41 for (i=0;i<s;i++) 42 if (b[i]) ans++; 43 printf("%d\n",ans); 44 } 45 }