{purple8}

##二分查找##

 

HDU - 1053

很久之前做过的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 }
View Code

 

UVA - 120

好像又回到最开始只会看题解的时候了-_-||

 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 }
》》》

 

UVA - 1451

数形结合,半年前费多大劲也没看很明白。。。

这次虽然理解了但还是写不出来,代码能力还是很弱=_=||

参考: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 }
View Code

 

UVA - 714

二分,一点细节没注意到又坑了好久。。。

 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 }
View Code

 

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 }
Easy

 

UVA - 12627

递归求解,感觉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 }
改了一点

 

UVA - 11093

读错题了,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 }
View Code

 

UVA - 1607

与非门电路

这个真的看不懂了,,过一阵再回来做吧。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 }
COPY

 

UVA - 12174 

方法一:滑动窗口,相对好理解一些。

 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 }
COPY

方法二:排除掉不可能的,剩下的就是可能的情况,有一点细节暂时理解不了

 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 }
COPY

 

posted @ 2017-07-12 23:09  yijiull  阅读(108)  评论(0编辑  收藏  举报