hihoCoder太阁最新面经算法竞赛2

A  任务分配

描述

给定 N 项任务的起至时间( S1E1 ), ( S2E2 ), ..., ( SNEN ), 计算最少需要多少台机器才能按时完成所有任务。

同一时间一台机器上最多进行一项任务,并且一项任务必须从头到尾保持在一台机器上进行。任务切换不需要时间。

输入

第一行一个整数 N,(1 ≤ N ≤ 100000),表示任务的数目。 以下 N 行每行两个整数 SiEi,(0 ≤ Si < Ei ≤ 1000000000),表示任务的起至时间。

输出

输出一个整数,表示最少的机器数目。

题解:线段树(区间更新,离散化)

代码:

 1 /*任务分配*/
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<map>
 5 using namespace std;
 6 
 7 const int maxn=2*1e5+10;
 8 
 9 struct data{
10     int s,e;
11     int ss,ee;
12 };
13         struct data line[maxn];
14         int point[maxn*2];
15 int tree[maxn*4];
16 int temp[maxn*4];
17 
18 int max(int a,int b)
19 {
20     return a<b?b:a;
21 }
22 
23 void Build(int l,int r,int n)
24 {
25     if(l==r)
26     {
27         tree[n]=0;
28         temp[n]=0;
29         return;
30     }
31     int mid=(l+r)/2;
32     Build(l,mid,n*2);
33     Build(mid+1,r,n*2+1);
34     tree[n]=max(tree[n*2],tree[n*2+1]);
35 }
36 void Updata(int l,int r,int p,int q,int n)
37 {
38     if(p<=l&&r<=q)
39     {
40         tree[n]++;
41         temp[n]+=1;
42         return;
43     }    
44     if(temp[n])
45     {
46         temp[n*2]+=temp[n];temp[n*2+1]+=temp[n];
47         tree[n*2]+=temp[n];tree[n*2+1]+=temp[n];
48         temp[n]=0;
49     }
50     int mid=(l+r)/2;
51     if(p<=mid)    Updata(l,mid,p,q,n*2);
52     if(q>mid)    Updata(mid+1,r,p,q,n*2+1);
53     tree[n]=max(tree[n*2],tree[n*2+1]);
54 }
55 int main()
56 {
57     int N;
58     while(scanf("%d",&N)!=EOF)
59     {
60 
61         for(int i=0;i<N;i++)
62         {
63             scanf("%d%d",&line[i].s,&line[i].e);
64             point[i*2]=line[i].s;point[i*2+1]=line[i].e;
65         }
66         sort(point,point+2*N);
67         map<int,int> a;
68         a[point[1]]=0;
69         for(int i=0;i<2*N;i++)
70         {
71             if(point[i]>point[i-1])
72                 a[point[i]]=a[point[i-1]]+1;
73             else
74                 a[point[i]]=a[point[i-1]];
75         }
76         for(int i=0;i<N;i++)
77         {
78             line[i].ss=a[line[i].s];
79             line[i].ee=a[line[i].e];
80         }
81         
82         //for(int i=0;i<N;i++)
83         //    printf("%d %d %d %d
",line[i].s,line[i].ss,line[i].e,line[i].ee);
84         
85         Build(1,maxn,1);
86         for(int i=0;i<N;i++)
87         {
88             Updata(1,maxn,line[i].ss+1,line[i].ee,1);
89         }
90         printf("%d
",tree[1]);
91     }
92     return 0;
93     
94  } 
View Code

B 岛屿

描述

给你一张某一海域卫星照片,你需要统计:

1. 照片中海岛的数目

2. 照片中面积不同的海岛数目

3. 照片中形状不同的海盗数目

其中海域的照片如下,"."表示海洋,"#"表示陆地。在"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。

.####..  
.....#.  
####.#.  
.....#.  
..##.#.  

上图所示的照片中一共有4座岛屿;其中3座面积为4,一座面积为2,所以不同面积的岛屿数目是2;有两座形状都是"####",所以形状不同的岛屿数目为3。

输入

第一行包含两个人整数:N 和 M,(1 ≤ NM ≤ 50),表示照片的行数和列数。

以下一个 N * M 的矩阵,表示表示海域的照片。

输出

输出3个整数,依次是照片中海岛的数目、面积不同的海岛数目和形状不同的海岛数目。

样例输入

5 7
.####..  
.....#.  
####.#.  
.....#.  
..##.#.  

样例输出

4 2 3


题解:BFS求联通块得出海岛的数目。在搜索时记录下海岛大小,放入map,最后得出面积不同的海岛数目。在搜索时将个海岛放入一个数组,这个数组记录了组成这个海岛所有#的位置,然后将这个数组排序。判断海岛是否相同,只要看其中#的个数是否相等,再看每个#相对第一个#的位置是否相同。

 代码:

  1 /*岛屿*/
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<map>
  5 #include<algorithm>
  6 #include<cmath>
  7 #include<queue>
  8 using namespace std;
  9 
 10 const int maxn=60;
 11 
 12 int N,M;
 13 char land[maxn][maxn];
 14 int vis[maxn][maxn];
 15 int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
 16 int ans1,ans2,ans3;
 17 map<int,int> a;
 18 
 19 struct data{
 20     int x,y;
 21     int num;
 22     int has;
 23 };
 24 struct data all[3000][3000];
 25 
 26 
 27 bool cmp2(struct data c,struct data d)
 28 {
 29     if(c.x!=d.x)
 30         return c.x<d.x;
 31     else
 32         return c.y<d.y;
 33 }
 34 
 35 int same(struct data c[],struct data d[])
 36 {
 37     int len=c[0].num;
 38     if(len==1)    return 1;
 39     int flag=1;
 40     for(int i=2;i<=len;i++)
 41     {
 42         if(((c[i].x-c[i-1].x)==(d[i].x-d[i-1].x))&&((c[i].y-c[i-1].y)==(d[i].y-d[i-1].y)))
 43             continue;
 44         else
 45         {
 46             flag=0;
 47             break;
 48         }
 49     }
 50     return flag;
 51 }
 52 void BFS(int x,int y)
 53 {
 54     vis[x][y]=1;
 55     queue<struct data> Q;
 56     struct data first,next;
 57     first.x=x;first.y=y;
 58     Q.push(first);
 59     all[ans1][0].num=0;
 60     while(!Q.empty())
 61     {
 62         first=Q.front();Q.pop();
 63         all[ans1][all[ans1][0].num+1].x=first.x;all[ans1][all[ans1][0].num+1].y=first.y;
 64         all[ans1][0].num++;
 65         for(int i=0;i<4;i++)
 66         {
 67             next.x=first.x+dx[i];next.y=first.y+dy[i];
 68             if(next.x<0||next.x>=N||next.y<0||next.y>=M)
 69                 continue;
 70             if(vis[next.x][next.y]==1)
 71                 continue;
 72             if(land[next.x][next.y]=='.')
 73                 continue;
 74                 
 75             Q.push(next);
 76             vis[next.x][next.y]=1;
 77         }
 78     } 
 79     a[all[ans1][0].num]++;
 80 }
 81 
 82 int main()
 83 {
 84     while(scanf("%d%d",&N,&M)!=EOF)
 85     {
 86         memset(land,0,sizeof(land));
 87         for(int i=0;i<N;i++)
 88             scanf("%s",land[i]);
 89         memset(vis,0,sizeof(vis));
 90         ans1=0;ans2=0;ans3=0;
 91         a.clear();
 92         for(int i=0;i<N;i++)
 93         {
 94             for(int j=0;j<M;j++)
 95             {
 96                 if(land[i][j]=='#'&&vis[i][j]==0)
 97                 {
 98                     BFS(i,j);
 99                     ans1++;
100                 }
101             }
102         }
103         ans2=a.size();
104         for(int i=0;i<ans1;i++)
105             sort(all[i],all[i]+all[i][0].num,cmp2);
106         for(int i=0;i<3000;i++)
107             all[i][0].has=0;
108         for(int i=0;i<ans1;i++)
109         {
110             if(all[i][0].has==1)
111                 continue;
112             for(int j=i+1;j<ans1;j++)
113             {
114                 if(all[j][0].has==0&&(all[i][0].num==all[j][0].num)&&same(all[i],all[j]))
115                 {
116                     ans3++;
117                     all[j][0].has=1;
118                 }
119             }
120             all[i][0].has=1;
121         }
122         printf("%d %d %d
",ans1,ans2,ans1-ans3);
123     }
124     return 0;
125 }
View Code

C 二进制小数

描述

给定一个十进制小数X,判断X的二进制表示是否是有限确定的。

例如0.5的二进制表示是0.1,0.75的二进制表示是0.11,0.3没有确定有限的二进制表示。

输入

第一行包含一个整数 T (1 ≤ T ≤ 10),表示测试数据的组数。

以下T行每行包含一个十进制小数 X (0 < X < 1)。 X一定是以"0."开头,小数部分不超过100位。

输出

对于每组输入,输出 X 的二进制表示或者NO(如果 X 没有确定有限的二进制表示)。

样例输入

3
0.5
0.75
0.3

样例输出

0.1
0.11
NO

题解:小数第二级制就是将小数乘2,得到整数部分,再取小数部分进行操作。那么什么时候这个小数无法用有限位的二进制表示呢?可以知道,要结束乘2的操作,那么肯定要小数部分为0。我们观察最后小数的最后一位,我们对小数不断乘2,最后一位也乘2,如果这个数在乘2后可以变成0,那么小数部分就可以缩短,直至全部为0。很容易知道,只有5可以在乘2之后得到0,其他数字都是不可以的。所以我们只需要不断模拟操作,同时检查小数最后一个数字是不是5。
代码:
 1 /*二进制小数*/
 2 #include<cstdio>
 3 #include<map>
 4 #include<cstring>
 5 using namespace std;
 6 
 7         int ans[100000];
 8         int s[150];
 9         int rear;
10         int flag=1;
11         
12 int muti()
13 {
14     for(int i=2;i<=rear;i++)
15         s[i]*=2;
16     for(int i=rear;i>=2;i--)
17     {
18         if(s[i]>=10)
19         {
20             s[i-1]++;
21             s[i]%=10;
22         }
23     }
24     for(rear=140;rear>=1;rear--)
25     {
26         if(s[rear]==0)    continue;
27         else    break;
28     }
29     if(rear!=1&&s[rear]!=5)
30         flag=0;
31 }
32 
33 
34 int main()
35 {
36     int T;    
37     scanf("%d",&T);
38     while(T--)
39     {
40         char S[150];
41         memset(S,0,sizeof(S));
42         scanf("%s",S);
43         memset(s,0,sizeof(s));
44         int len=strlen(S);
45         for(int i=2;i<len;i++)
46             s[i]=S[i]-'0';
47         memset(ans,0,sizeof(ans));
48         len=1;
49         flag=1;
50         rear=strlen(S)-1;
51         while(1)
52         {
53             muti();
54             if(flag==0)    break;
55             ans[len++]=s[1];
56             s[1]=0;
57             if(rear==1)    break;
58         } 
59         if(flag==0)
60             printf("NO
");
61         else
62         {
63             printf("0.");
64             for(int i=1;i<len;i++)
65                 printf("%d",ans[i]);
66             printf("
");
67         }
68         memset(S,0,sizeof(S));
69     }
70     return 0;
71 }
View Code
原文地址:https://www.cnblogs.com/yepiaoling/p/5547578.html