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 }
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 }
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 }
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 }
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 }
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 }
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 }
------------------------昏割线-------------------------
首先 是 还犯了数组开小这样的错误
然后..用memset T 了一发.......
然后就是 dp 不够
然后爆搜的话一定多想想剪枝...
还有就是读题感觉要读好多遍...英语捉急
干巴爹></