ID Title Solved Source
  2396 Budget 285 Tehran 2003 Preliminary
Tehran 2003 Preliminary 2397 Spiderman 307 Tehran 2003 Preliminary
Tehran 2003 Preliminary 2398 Toy Storage 405 Tehran 2003 Preliminary
  2399 A Mayor Problem 25 Tehran 2003 Preliminary
  2400 Supervisor, Supervisee 151 Tehran 2003 Preliminary
  2401 Street Polygon 12 Tehran 2003 Preliminary
Tehran 2003 Preliminary 2402 Palindrome Numbers 830 Tehran 2003 Preliminary

    (边做边更新~)

    Spiderman:

    蜘蛛男可以爬上爬下,给定一定距离,或上或下,最终到达原地点。

    一开始维护一个优先队列,很明显的超时了,于是乎往DP方面想,发现所有点的和最大为1000,则可以设计一个 DP[ 第几个点 ][ 此时的高度 ],那么DP[N][0]则为最小楼高,状态转移为(具体看代码):

    1、往上爬,若最优值大于此时该点的值,那么不用变化值,反之,最有值为该点高度值

    2、往下爬,最优值不变

    最后回朔一遍,输出上上下下就好了。

代码
1 #include <cstdio>
2
3  using namespace std;
4
5  const int maxn = 1004;
6 const int inf = 199999999;
7
8 int n, a[maxn], dp[maxn][maxn];
9
10 struct node { int x, y; char c; } f[maxn][maxn];
11
12 void print(int x, int y)
13 {
14 if(f[x][y].x == -1)
15 return ;
16 print(f[x][y].x , f[x][y].y);
17 printf("%c", f[x][y].c);
18 }
19
20 void solve()
21 {
22 for(int i=1; i <= n; i++) {
23 for(int j=0; j < maxn; j++) {
24 dp[i][j] = inf;
25 f[0][j].x = -1;
26 }
27 }
28
29 dp[1][ a[1] ] = a[1];
30 f[1][ a[1] ].x = 0;
31 f[1][ a[1] ].y = 0;
32 f[1][ a[1] ].c = 'U';
33
34 for(int i=2; i <= n; i++) {
35 for(int j=0; j < maxn; j++) {
36
37 if(j - a[i] >= 0 && dp[i][j] >= dp[i - 1][j - a[i]])
38 {
39 if(dp[i - 1][j - a[i]] >= j)
40 dp[i][j] = dp[i - 1][j - a[i]];
41 else
42 dp[i][j] = j;
43 f[i][j].x = i - 1;
44 f[i][j].y = j - a[i];
45 f[i][j].c = 'U';
46 }
47
48 if(j - a[i] >= 0 && dp[i][j - a[i]] >= dp[i - 1][j])
49 {
50 dp[i][j - a[i]] = dp[i - 1][j];
51 f[i][j - a[i]].x = i - 1;
52 f[i][j - a[i]].y = j;
53 f[i][j - a[i]].c = 'D';
54 }
55
56 }
57 }
58 if(dp[n][0] == inf)
59 printf("IMPOSSIBLE");
60 else
61 print(n , 0);
62 puts("");
63 }
64
65 int main()
66 {
67 int cas;
68 scanf("%d", &cas);
69 while(cas --)
70 {
71 scanf("%d", &n);
72 for(int i=1; i <= n; i++)
73 scanf("%d", &a[i]);
74 solve();
75 }
76 return 0;
77 }
78

    Toy Storage:

    用n个板子把一个箱子分成n + 1块,然后丢进去m个玩具,最后统计t (t > 0)的格子有多少个。

    先给线段从左到右排序,然后每次迭代,若点在该直线的左边,则这个点落在距离这条直线左边最近格子上,否则迭代到下一条直线

代码
1 #include <cstdio>
2 #include <algorithm>
3
4  using namespace std;
5
6  const double inf = 1999999999;
7  const int maxn = 1005;
8
9 struct line { double k, b; } L[maxn]; //直线方程 y = kx + b
10 struct node { double x, y; } a[maxn];
11
12 int n, m, toy[maxn], ans[maxn];
13 double x1, y1, x2, y2;
14
15 bool cmp(const node A, const node B)
16 {
17 return A.x < B.x;
18 }
19
20 line get(double x, double y)
21 {
22 line tmp;
23 double k , b;
24 if(x == y) {
25 k = inf;
26 b = x;
27 }
28 else {
29 k = (y2 - y1) / (y - x);
30 b = y1 - x * k;
31 }
32 tmp.k = k;
33 tmp.b = b;
34 return tmp;
35 }
36
37 bool check(double x, double y, line ll)
38 {
39 if(ll.k == inf) {
40 if(x <= ll.b)
41 return true;
42 return false;
43 } else {
44 double Y = ll.k * x + ll.b;
45 if(ll.k > 0 && Y <= y)
46 return true;
47 else if(ll.k < 0 && Y >= y)
48 return true;
49 else
50 return false;
51 }
52 }
53
54 void solve()
55 {
56 double x, y;
57 for(int i=0; i < m; i++)
58 {
59 scanf("%lf %lf", &x, &y);
60 bool flag = false;
61 for(int j=0; j < n; j++)
62 {
63 if(check(x , y, L[j]))
64 {
65 flag = true;
66 toy[j] ++;
67 break;
68 }
69 }
70 if(!flag) toy[n] ++;
71 }
72 for(int i=0; i <= n; i++)
73 ans[ toy[i] ] ++;
74 puts("Box");
75 for(int i=1; i <= m; i++)
76 if(ans[i] != 0)
77 printf("%d: %d\n", i , ans[i]);
78 }
79
80 int main()
81 {
82 while(~scanf("%d", &n), n)
83 {
84 memset(toy, 0, sizeof(toy));
85 memset(ans, 0, sizeof(ans));
86
87 scanf("%d %lf %lf %lf %lf", &m, &x1, &y1, &x2, &y2);
88 for(int i=0; i < n; i++)
89 scanf("%lf %lf", &a[i].x, &a[i].y);
90
91 sort(a, a + n, cmp);
92 for(int i=0; i < n; i++)
93 L[i] = get(a[i].x , a[i].y);
94
95 solve();
96 }
97 return 0;
98 }

    Palindrome Numbers:

    有这个规律: 1位数 : 9个回文 2位数 : 9个回文 3位数 : 90个回文 4位数 : 90个回文 ...

    既首尾有9种选择,而中间有10种选择。又前后需要一致,所以统计的时候只需要统计前(n + 1) / 2项即可

代码
1 #include <cstdio>
2 using namespace std;
3
4 typedef __int64 LL;
5
6 const int maxn = 10000;
7 const LL inf = 1000000000 * 2;
8
9 int LEN;
10 LL sum[maxn], a[maxn], digit[maxn], n, tmp;
11
12 void init()
13 {
14 LL i;
15 sum[1] = 9 , sum[2] = 18;
16 a[1] = 9 , a[2] = 9;
17 for(i=3; ; i += 2)
18 {
19 a[i] = a[i - 1] * 10;
20 sum[i] = sum[i - 1] + a[i];
21
22 a[i + 1] = a[i];
23 sum[i + 1] = sum[i] + a[i + 1];
24
25 if(sum[i + 1] >= inf)
26 break;
27 }
28 LEN = i + 1;
29 }
30
31 int main()
32 {
33 init();
34 while(~scanf("%I64d", &n) , n)
35 {
36 int i;
37 for(i=1; i <= LEN; i++)
38 {
39 if(sum[i] >= n) {
40 n -= sum[i - 1];
41 break;
42 }
43 }
44 LL tmp = 1;
45 for(int j=2; j <= ((i + 1) >> 1); j++)
46 tmp *= 10;
47 tmp += n - 1;
48
49 printf("%I64d", tmp);
50
51 if(i & 1)
52 tmp /= 10;
53 while(tmp) {
54 int t = tmp % 10;
55 printf("%d", t);
56 tmp /= 10;
57 }
58 puts("");
59 }
60 return 0;
61 }

 

 

   

相关文章:

  • 2022-01-17
  • 2021-08-20
  • 2022-01-31
  • 2021-09-15
  • 2021-09-06
猜你喜欢
  • 2021-09-19
  • 2021-06-06
  • 2022-12-23
  • 2022-01-28
  • 2021-05-18
  • 2021-07-20
  • 2021-11-25
相关资源
相似解决方案