正在缓慢返回div1的路上,今天这场rating+=63,与上场不同,这次是真的被俄罗斯人民的英语坑了……否则这场有可能直接回div1的……

 

A. Fancy Fence

http://codeforces.com/problemset/problem/270/A

给出一个角度a,问是否有一个内角为a的正n边形。

1.正n边形内角和为(n-2)*180,枚举一下n就好了。

2.专业点的解法是判断360%(180-a)==0即为yes,否则为no。原理是凸多边形的补角和为360度。

代码略

 

B. Multithreading

被坑的最严重的一道题,看了好几遍也没完全看懂题目描述,特别是那两个condition至今不理解,结合样例艰难推测出题意。

有n个线程,编号1~n,对每个线程x,如果x收到了新消息则x会跳到序列的首位。给出每个线程在刷新之前的老位置(刷新之后为1……n),

求两次刷新之间“确定”有新消息的线程个数。

首先的想法是类似逆序数,对于每一个线程x,如果在x后面有比他小的数,则x一定有新消息。统计有多少个这样的x即可。交上去wa了。

可以很显然发现这种情况:2 3 1 5 4,符合上述条件的有2 3 5,但实际上5已经跳到了4的前面,而1又在5的前面,说明1也一定有新消息,否则5应在1的前面。

因此,策略应该修改为从右到左扫描序列,发现第一个x满足在x右边的数字中存在比x小的数字,这从x开始到最左边的线程都一定有新消息。

View Code
 1 //3064426     Feb 2, 2013 6:55:11 PM     rookie052     269A - Magical Boxes     GNU C++     Accepted     78 ms     0 KB 
 2 #include <cstdio>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <string>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <queue>
 9 #include <cmath>
10 using namespace std;
11 typedef long long ll;
12 const double PI = acos(-1);
13 const double EPS = 1e-12;
14 
15 int minval[110000];
16 int n;
17 int a[110000];
18 int main()
19 {
20     scanf("%d",&n);
21     for(int i=1;i<=n;i++){
22         scanf("%d",&a[i]);
23     }
24     minval[n+1] = 1<<29;
25     int ans = 0;
26     for(int i=n;i>=1;i--){
27         minval[i] = min(minval[i+1],a[i]);
28         if(a[i] > minval[i+1]){
29             ans = i;
30             break;
31         }
32     }
33     printf("%d\n",ans);
34 
35     return 0;
36 }

 

C. Magical Boxes ( &div1 A )

http://codeforces.com/problemset/problem/269/A

给n种箱子,每种有一个大小k和数量a,四个大小为k得箱子可以放到一个大小为k+1的箱子里面。求一个最小的箱子,能装下所有给出的箱子。

有这么几个点值得注意:

1.箱子是平面的= =!虽然不符合常识但还是很快能根据描述发现这点的;

2.样例1和图片不是一个,给出了announcement;

3.不同种类(大小)的箱子之间可以单独考虑,这点很关键,因为层数是可以无限嵌套的,而且保证k不相同,否则应该将k相等的合并起来;

4.算是本题最大的坑,好在pretest里包含了这种情况,否则一定会挂很多人。那就是题目要求最后选择的箱子大小一定要“严格”大于其包含的箱子大小。这个条件实际上只适用于个数为1的情况,即一个1不能放在大小为1的箱子里,至少放在大小为2的箱子里;而四个1是可以放在一个大小为2的箱子里面的,不需要再增大到3。箱子个数为1的情况很容易被忽视。

综上,对每一种型号的box,不断以4个为一组进行合并,合并一轮体积+1,直到合并为1个;个数为1的情况单独处理。

答案即为每种型号得到的最终箱子大小的最大值。

View Code
 1 //3064426     Feb 2, 2013 6:55:11 PM     rookie052     269A - Magical Boxes     GNU C++     Accepted     78 ms     0 KB 
 2 #include <cstdio>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <string>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <queue>
 9 #include <cmath>
10 using namespace std;
11 typedef long long ll;
12 const double PI = acos(-1);
13 const double EPS = 1e-12;
14 
15 int n;
16 
17 int main(){
18 
19     int k,a;
20     int ans = 0;
21     scanf("%d",&n);
22     while(n--){
23         scanf("%d%d",&k,&a);
24         if(a==1){
25             ans = max(k+1,ans);
26         }
27         while(a>1){
28             if(a%4==0){
29                 a = a/4;
30             }
31             else{
32                 a = a/4+1;
33             }
34             k++;
35         }
36         ans = max(ans,k);
37     }
38     printf("%d\n",ans);
39 
40     return 0;
41 }

 

D. Greenhouse Effect ( &div1 B)

http://codeforces.com/problemset/problem/269/B

给出n棵,共m种树,种在一条无限长的直线上,坐标范围0到正无穷。求移动最少数量的树木,使该行树木按种类从1...m排列

1,很快可以发现既然座标按x递增给出,则这里坐标就没有了意义,因为任意两点间有无数个点,可以放无数树,对结果有影响的只是树木间的相对位置关系。

2,对于两颗同一种的树x和y,若起始时x在y的左边,则最终x也应在y左边,把x放在y的右边也许同样能得到最小代价,但是是没有意义的。这样树的最终排列数序就可以确定下来了。a[i]表示最终结果中,第i个位置放的是原序列的第几棵树。

3,问题就变成了原序列x(1...n)用最少的代价转变为a(1...n),这里移动数目的操作是挖出来再埋上,不是两两交换,需注意一下。

4,对于3问,求最少的移动数量,等价于求一个最长上升序列,序列中的树木保持不动,其他的都是需要移动的。得解。

View Code
 1 //3064747     Feb 2, 2013 7:58:45 PM     rookie052     269B - Greenhouse Effect     GNU C++     Accepted     62 ms     100 KB 
 2 #include <cstdio>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <string>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <queue>
 9 #include <cmath>
10 using namespace std;
11 typedef long long ll;
12 const double PI = acos(-1);
13 const double EPS = 1e-12;
14 
15 int n,m;
16 struct NODE{
17     int v,p;
18 }node[6000];
19 bool cmp(NODE a,NODE b){
20     if(a.v == b.v)    return a.p < b.p;
21     return a.v<b.v;
22 }
23 int a[6000];
24 int dp[5100];
25 
26 int main()
27 {
28     scanf("%d%d",&n,&m);
29     double tmp;
30     for(int i=0;i<n;i++){
31         scanf("%d%lf",&node[i].v,&tmp);
32         node[i].p = i;
33     }
34     sort(node,node+n,cmp);
35     for(int i=0;i<n;i++){
36         a[node[i].p] = i;
37     }
38     
39     int maxval = 1;
40     memset(dp,0,sizeof(dp));
41     for(int i=0;i<n;i++){
42         dp[i] = 1;
43         for(int j=i-1;j>=0;j--){
44             if(a[j] < a[i]){
45                 if(dp[j]+1 > dp[i]){
46                     dp[i] = dp[j]+1;
47                 }
48             }
49         }
50         maxval = max(maxval,dp[i]);
51     }
52     printf("%d\n",n-maxval);
53 
54 
55     return 0;
56 }

 

E. Flawed Flow ( &div1 C )

待续

 

posted on 2013-02-03 00:01  NKHe!!oWor!d  阅读(318)  评论(0编辑  收藏  举报