2016.9.15 --- 2014 北京

1001 A Curious Matt

求最大的平均速度

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 const int maxn = 1e5+5;
 9 int n,m;
10 
11 struct node{
12     int x,t;
13 }a[maxn];
14 
15 int cmp(node n1,node n2){
16     return n1.t < n2.t;
17 }
18 
19 void solve(){
20     double ans = 0;
21     sort(a+1,a+n+1,cmp);
22     for(int i = 2;i <= n;i++){
23         int fz = abs(a[i].x-a[i-1].x);
24         int fm = a[i].t - a[i-1].t;
25         double res = (1.0*fz)/(1.0*fm);
26         ans = max(ans,res);
27     }
28     printf("%.2lf\n",ans);
29 }
30 
31 int main(){
32     int T;
33     int kase = 0;
34     scanf("%d",&T);
35     while(T--){
36         scanf("%d",&n);
37         for(int i = 1;i <= n;i++){
38             scanf("%d %d",&a[i].t,&a[i].x);
39         }
40         printf("Case #%d: ",++kase);
41         solve();
42     }
43     return 0;
44 }
View Code

 

 

1002 Black And White

n*m 的格子,一共 k 种颜色

c1 + c2 + c3 +...+ck = n*m 求相邻格子的颜色不同的染色方案

题解说的本应该是构造,姿势好的爆搜也可以过

剪枝 是 当一种颜色超过剩余格子的一半的时候,就不行了

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 int ans[15][15],c[105],n,m,k;
 8 int flag;
 9 int cnt[105];
10 
11 void print(){
12     puts("YES");
13     for(int i = 1;i <= n;i++){
14         for(int j = 1;j < m;j++) printf("%d ",ans[i][j]);
15         printf("%d\n",ans[i][m]);
16     }
17 }
18 
19 bool dfs(int x,int y){
20     for(int i = 1;i <= k;i++){
21         if((n*m - (x-1)*m-y+2)/2 < c[i]) return false;
22     }
23     for(int i = 1;i <= k;i++){
24         if(c[i]){
25             if(ans[x][y-1] == i || ans[x-1][y] == i) continue;
26             ans[x][y] = i;
27             //printf("ans[%d][%d] = %d\n",x,y,ans[x][y]);
28             c[i]--;
29             if(x == n && y == m){print();return true;}
30             if(y != m && dfs(x,y+1)) return true;
31             if(y == m && dfs(x+1,1)) return true;
32             c[i]++;
33         }
34     }
35     return false;
36 }
37 
38 int cmp(int x,int y){
39     return x > y;
40 }
41 
42 void solve(){
43     flag = 0;
44     for(int i = 1;i <= k;i++){
45         if(c[i] > (n*m+1)/2){
46             puts("NO");
47             return;
48         }
49     }
50     memset(ans,0,sizeof(ans));
51     if(k == 1 && n*m != 1){
52         puts("NO");
53         return;
54     }
55     if(dfs(1,1)) return;
56     puts("NO");
57 }
58 
59 int main(){
60     int T,kase = 0;
61     scanf("%d",&T);
62     while(T--){
63         scanf("%d %d %d",&n,&m,&k);
64         for(int i = 1;i <= k;i++) {
65             scanf("%d",&c[i]);
66         }
67         printf("Case #%d:\n",++kase);
68         solve();
69     }
70     return 0;
71 }
View Code

 

 

1003 Collision

给出一个矩形.两个开始的点,运动速度都相同,运动方向是 (1,1)碰到矩形的边的时候,会发生弹性碰撞

求第一次碰撞的坐标..

第三个样例画不出来怎么撞的啊...第二个点不是运动出去了么...wwww

不懂

 

1004 Dire Wolf

有 n 只狼排成一排,每只狼有一个初始的伤害值ai ,同时每只狼还有附加的伤害值 bi ,每只狼可以给它相邻的狼增加伤害值,杀死一只狼需要的伤害值 是 ai + bi-1,bi+1

可以任意选择杀狼的顺序,问杀死这 n 只狼需要的最小的伤害值

比赛的时候,还是没太搞清楚伤害值该怎么去算,dp 顺序有问题,而且转移也有问题

dp[i][j] 表示 杀死从i 到 j 的狼所需要的最小伤害值

枚举这段区间最后杀死的狼 是 k ,那么杀死这只狼的代价,就是 a[k] + b[i-1] + b[j+1] (因为它是最后一只狼,左右两端是 i-1,j+1)

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 const int maxn = 205;
 9 int a[maxn],b[maxn],dp[maxn][maxn];
10 const int INF = (1<<30)-1;
11 int n;
12 
13 void solve(){
14     dp[0][0] = 0;
15     b[0] = b[n+1] = 0;
16     for(int i = 1;i <= n;i++){
17         for(int j = 1;j <= n;j++){
18             if(i == j) dp[i][i] = a[i]+b[i-1]+b[i+1];
19             else dp[i][j] = INF;
20         }
21     }
22 
23     for(int l = 2;l <= n;l++){
24         for(int s = 1;s+l-1 <= n;s++){
25             int e = s+l-1;
26             for(int k = s;k <= e;k++){
27                 if(k == s) dp[s][e] = min(dp[s][e],dp[s+1][e]+a[s]+b[s-1]+b[e+1]);
28                 else if(k == e) dp[s][e] = min(dp[s][e],dp[s][e-1]+a[e]+b[e+1]+b[s-1]);
29                 else{
30                     dp[s][e] = min(dp[s][e],dp[s][k-1]+dp[k+1][e]+a[k]+b[s-1]+b[e+1]);
31                 }
32             }
33         }
34     }
35     printf("%d\n",dp[1][n]);
36 }
37 
38 int main(){
39     int T,kase = 0;
40     scanf("%d",&T);
41     while(T--){
42         scanf("%d",&n);
43         for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
44         for(int i = 1;i <= n;i++) scanf("%d",&b[i]);
45         printf("Case #%d: ",++kase);
46         solve();
47     }
48     return 0;
49 }
View Code

 

 

1005 Everlasting L

给出 一个点集,称这样的点集是 good 的

(x,y),(x+1,y),....(x+a,y),(x,y+1),(x,y+2),.... (x,y+b) gcd(a,b) = 1

问点集中满足,A ,B都是 good 且 A交B为空 的有多少对

不会捉..搜一个题解说是dp

 

1006 Fluorescent

一共 m 个开关,每个开关控制一些灯

最后灯亮的个数为 X ,求 X^3的期望

设最后灯亮的情况为 x1 + x2 + x3 +... +xn

所以 x^3 可以写成 (x1+x2+x3+...+xn)*(x1+x2+...+xn)*(x1+x2+...+xn)

x^3 就是 sum(xi*xj*xk) (1 <= i ,j , k <= n)只有当 xi ,xj ,xk 都为 1 的时候才对答案有贡献

dp[s][t] 表示前 s 个开关 (i,j,k,)的状态为 t 的方案数,所以就枚举i, j, k 累加 dp[m][7] 

.........说起来,听过状压dp不知道多少次了..但这还是第一次真正意义写状压dp叭

纪念一发><

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 int a[105][105],n,m;
 9 LL dp[55][8];
10 const long long mod = 1e9+7;
11 
12 void solve(){
13     LL ans = 0LL;
14     for(int i = 0;i < n;i++){
15         for(int j = 0;j < n;j++){
16             for(int k = 0;k < n;k++){    
17                 memset(dp,0LL,sizeof(dp));
18                 dp[0][0] = 1LL;
19                 for(int s = 1;s <= m;s++){
20                     int u = a[s][i] + a[s][j]*2 + a[s][k]*4;
21                     for(int t = 0;t < 8;t++){
22                         dp[s][t] = (dp[s-1][t] + dp[s-1][t^u]) % mod;
23                     }
24                 }
25                 ans = (ans+dp[m][7]) % mod;
26             }
27         }
28     }
29     printf("%I64d\n",ans);
30 }
31 
32 int main(){
33     int T,kase = 0;
34     scanf("%d",&T);
35     while(T--){
36         scanf("%d %d",&n,&m);
37         int x,y;
38         memset(a,0,sizeof(a));
39         for(int i = 1;i <= m;i++){
40             scanf("%d",&x);
41             for(int j = 1;j <= x;j++) {
42                 scanf("%d",&y);
43                 a[i][y-1] = 1;
44             }
45         }
46         printf("Case #%d: ",++kase);
47         solve();
48     }
49     return 0;
50 }
View Code

 

 

 

 

 

1007 GRE Words Once More!

过的人好少..题都没读了

 

1008 Happy Matt Friends

 看有人说正解应该是高斯消元

dp水果的..dp[i][j] 表示前 i 个数异或起来为 j 的方案数

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 const int maxn = 1e6+5;
 9 const int N = (1<<20)-1;
10 int n,a[maxn],m;
11 LL dp[45][N];
12 LL p[maxn];
13 
14 void solve(){
15     dp[0][0] = 1;
16     for(int i = 1;i <= n;i++){
17         for(int j = 0;j < N;j++){
18             dp[i][j] = (dp[i-1][j]+dp[i-1][j^a[i]]);
19         }
20     }
21     LL ans = 0LL;
22     for(int i = 0;i < m;i++) {
23         ans = ans+dp[n][i];
24         //printf("dp[n][%d] = %I64d\n",i,dp[n][i]);
25     }
26     LL res = p[n] - ans;
27     printf("%I64d\n",res);
28 }
29 
30 int main(){
31     int T,kase = 0;
32     p[0] = 1LL;
33     for(int i = 1;i <=50;i++) p[i] = p[i-1]*2LL;
34     scanf("%d",&T);
35     while(T--){
36         scanf("%d %d",&n,&m);
37         for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
38             printf("Case #%d: ",++kase);
39         solve();
40     }
41     return 0;
42 }
View Code

 

1009 Intersection

圆环相交的面积

SA交SB - Sa交SB - SA交sb + sa交sb

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <cmath>
  4 #include <iomanip>
  5 #include <vector>
  6 #include <iostream>
  7 using namespace std;
  8 
  9 const double PI = acos(-1.0);
 10 const int INF = (1<<30)-1;
 11 
 12 //lrj计算几何模板
 13 struct Point
 14 {
 15     double x,y;
 16     Point(double x=0,double y=0) :x(x),y(y) {}
 17 };
 18 typedef Point Vector;
 19 
 20 Point read_point(void)
 21 {
 22     double x, y;
 23     scanf("%lf%lf", &x, &y);
 24     return Point(x, y);
 25 }
 26 
 27 const double EPS = 1e-10;
 28 
 29 //向量+向量=向量 点+向量=点
 30 Vector operator + (Vector A, Vector B)    { return Vector(A.x + B.x, A.y + B.y); }
 31 
 32 //向量-向量=向量 点-点=向量
 33 Vector operator - (Vector A, Vector B)    { return Vector(A.x - B.x, A.y - B.y); }
 34 
 35 //向量*数=向量
 36 Vector operator * (Vector A, double p)    { return Vector(A.x*p, A.y*p); }
 37 
 38 //向量/数=向量
 39 Vector operator / (Vector A, double p)    { return Vector(A.x/p, A.y/p); }
 40 
 41 bool operator < (const Point& a, const Point& b)
 42 { return a.x < b.x || (a.x == b.x && a.y < b.y); }
 43 
 44 int dcmp(double x)
 45 { if(fabs(x) < EPS) return 0; else return x < 0 ? -1 : 1; }
 46 
 47 bool operator == (const Point& a, const Point& b)
 48 { return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0; }
 49 
 50 /**********************基本运算**********************/
 51 
 52 //点积
 53 double Dot(Vector A, Vector B)
 54 { return A.x*B.x + A.y*B.y; }
 55 //向量的模
 56 double Length(Vector A)    { return sqrt(Dot(A, A)); }
 57 
 58 //向量的夹角,返回值为弧度
 59 double Angle(Vector A, Vector B)
 60 { return acos(Dot(A, B) / Length(A) / Length(B)); }
 61 
 62 //叉积
 63 double Cross(Vector A, Vector B)
 64 { return A.x*B.y - A.y*B.x; }
 65 
 66 //向量AB叉乘AC的有向面积
 67 double Area2(Point A, Point B, Point C)
 68 { return Cross(B-A, C-A); }
 69 
 70 //向量A旋转rad弧度
 71 Vector VRotate(Vector A, double rad)
 72 {
 73     return Vector(A.x*cos(rad) - A.y*sin(rad), A.x*sin(rad) + A.y*cos(rad));
 74 }
 75 
 76 /**********************圆的相关计算**********************/
 77 struct Line
 78 {//有向直线
 79     Point p;
 80     Vector v;
 81     double ang;
 82     Line()    { }
 83     Line(Point p, Vector v): p(p), v(v)    { ang = atan2(v.y, v.x); }
 84     Point point(double t)
 85     {
 86         return p + v*t;
 87     }
 88     bool operator < (const Line& L) const
 89     {
 90         return ang < L.ang;
 91     }
 92 };
 93 
 94 struct Circle
 95 {
 96     Point c;
 97     double r;    //半径
 98     Point point(double a)
 99     {//求对应圆心角的点
100         return Point(c.x + r*cos(a), c.y + r*sin(a));
101     }
102 };
103 
104 double sqr(double x){return x*x;}
105 
106 double Dis(Point a,Point b){
107     double l = sqr(a.x-b.x);
108     double r = sqr(a.y-b.y);
109     return sqrt(sqr(a.x-b.x) + sqr(a.y-b.y));
110 }
111 
112 double Intersection_area(Circle a,Circle b){  
113         double dis=Dis(a.c,b.c);
114         if(a.r==0||b.r==0||dis>=a.r+b.r)return 0;  
115         else if(dis<=fabs(a.r-b.r))return PI*sqr(min(a.r,b.r));  
116         else{  
117             double angA = 2*acos( (sqr(a.r)+sqr(dis)-sqr(b.r))/(2*a.r*dis) );  
118             double angB = 2*acos( (sqr(b.r)+sqr(dis)-sqr(a.r))/(2*b.r*dis) );  
119             double areaA = sqr(a.r)*(angA-sin(angA))/2;  
120             double areaB = sqr(b.r)*(angB-sin(angB))/2;  
121             return areaA+areaB;  
122         }  
123 }
124 
125 Circle A,a,B,b;
126 double r,R;
127 
128 void solve(){
129     double p1 = Intersection_area(A,B);
130     double p2 = Intersection_area(b,A);
131     double p3 = Intersection_area(a,B);
132     double p4 = Intersection_area(a,b);
133     printf("%.6lf\n",p1-p2-p3+p4);
134 }
135 
136 int main(){
137     int T,kase = 0;
138     scanf("%d",&T);
139     while(T--){
140         scanf("%lf %lf",&r,&R);
141         scanf("%lf %lf",&A.c.x,&A.c.y);
142         scanf("%lf %lf",&B.c.x,&B.c.y);
143         a.c = A.c;
144         a.r = r;A.r = R;
145         b.c = B.c;
146         b.r = r;B.r = R;
147         printf("Case #%d: ",++kase);
148         solve();
149     }
150     return 0;
151 }
View Code

 

 

1010 Just A Mistake

 过的人好少..也没读题了

 

1011 K.Bro Sorting

 给一列数,每次可以随意选择一个数,如果这个数后面相邻的那个数比他小,就一直往后换,直到不能换,这样叫做一轮

问最少需要多少轮,将这列数变成升序的

因为一个数如果后面有比它小的数的话,肯定都是要换到后面去的

所以就看这样的数有多少个

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 1e6+5;
 8 int n,a[maxn];
 9 
10 void solve(){
11     int minn = a[n];
12     int ans = 0;
13     for(int i = n-1;i >= 1;i--){
14         if(a[i] > minn){
15             ans++;
16         }
17         else minn = a[i];
18     }
19     printf("%d\n",ans);
20 }
21 
22 int main(){
23     int T,kase = 0;
24     scanf("%d",&T);
25     while(T--){
26         scanf("%d",&n);
27         for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
28         printf("Case #%d: ",++kase);
29         solve();
30     }
31     return 0;
32 }
View Code

 

------------------------昏割线-------------------------

首先 是 还犯了数组开小这样的错误

然后..用memset T 了一发.......

然后就是 dp 不够

然后爆搜的话一定多想想剪枝...

还有就是读题感觉要读好多遍...英语捉急

干巴爹></

 

转载于:https://www.cnblogs.com/wuyuewoniu/p/5878035.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值