SRM473

250pt:

题意:在二维平面上,给定3种,左转、右转,以及前进一步,的指令序列循环执行,问整个移动过程是否是发散的。

思路:直接模拟一个周期,然后判断1.方向是否和初始时不同 2.是否在原来的点

        满足其一便是收敛。具体画个图便明白

code:

 1 #line 7 "SequenceOfCommands.cpp"
 2 #include <cstdlib>
 3 #include <cctype>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <vector>
 9 #include <string>
10 #include <iostream>
11 #include <sstream>
12 #include <map>
13 #include <set>
14 #include <queue>
15 #include <stack>
16 #include <fstream>
17 #include <numeric>
18 #include <iomanip>
19 #include <bitset>
20 #include <list>
21 #include <stdexcept>
22 #include <functional>
23 #include <utility>
24 #include <ctime>
25 using namespace std;
26 
27 #define PB push_back
28 #define MP make_pair
29 
30 #define REP(i,n) for(i=0;i<(n);++i)
31 #define FOR(i,l,h) for(i=(l);i<=(h);++i)
32 #define FORD(i,h,l) for(i=(h);i>=(l);--i)
33 
34 typedef vector<int> VI;
35 typedef vector<string> VS;
36 typedef vector<double> VD;
37 typedef long long LL;
38 typedef pair<int,int> PII;
39 const int g[4][2] = {{1, 0},{0,-1},{-1, 0},{0, 1}};
40 
41 class SequenceOfCommands
42 {
43         public:
44         string whatHappens(vector <string> commands)
45         {
46                 string S = accumulate(commands.begin(), commands.end(), string(""));
47                 int x = 0, y = 0, dir = 0;
48                 int n = S.size();
49                 for (int i = 0; i < n; ++i){
50                     if (S[i] == 'L') dir = (dir + 3) % 4;
51                     if (S[i] == 'R') dir = (dir + 1) % 4;
52                     if (S[i] == 'S'){
53                          x += g[dir][0];
54                          y += g[dir][1];
55                     }
56                 }
57                 if (x == 0 && y == 0) return "bounded";
58                 if (dir != 0) return "bounded";
59                 return "unbounded";
60         }
61 };
View Code

500pt:

题意:将圆周 n<= 10^6等分,编号0~n-1,现在上面选取m <= 10^5个点,给定整数a b c,选择的第i个点的下标为(a*a*i+b*i+c)%n,如果已经被选过则选下一个木有被选的点。问这些点能构成多少个直角三角形。

思路:直角三角形必须经过圆心。所以n为奇数必然无解。

        否则先求出这m个点。每次求完后标记下,并用并查集加速。

code:

 1 #line 7 "RightTriangle.cpp"
 2 #include <cstdlib>
 3 #include <cctype>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <vector>
 9 #include <string>
10 #include <iostream>
11 #include <sstream>
12 #include <map>
13 #include <set>
14 #include <queue>
15 #include <stack>
16 #include <fstream>
17 #include <numeric>
18 #include <iomanip>
19 #include <bitset>
20 #include <list>
21 #include <stdexcept>
22 #include <functional>
23 #include <utility>
24 #include <ctime>
25 using namespace std;
26 
27 #define PB push_back
28 #define MP make_pair
29 
30 #define REP(i,n) for(i=0;i<(n);++i)
31 #define FOR(i,l,h) for(i=(l);i<=(h);++i)
32 #define FORD(i,h,l) for(i=(h);i>=(l);--i)
33 
34 typedef vector<int> VI;
35 typedef vector<string> VS;
36 typedef vector<double> VD;
37 typedef long long LL;
38 typedef pair<int,int> PII;
39 int fa[1200000];
40 bool vis[1200000];
41 
42 class RightTriangle
43 {
44         public:
45         int find(int k){
46             return !vis[k] ? k : fa[k] = find(fa[k]);
47         }
48         long long triangleCount(int n, int m, long long a, long long b, long long c)
49         {
50                if (n & 1) return 0;
51                memset(vis, 0, sizeof(vis));
52                for (int i = 0; i < n; ++i) fa[i] = (i + 1) % n;
53                for (int i = 0; i < m; ++i)
54                    vis[find((a * i * i + b*i +c) % n)] = true;
55                long long ans = 0;
56                for (int i = 0; i < n / 2; ++i)
57                    if (vis[i] && vis[i + n / 2]) ++ ans;
58                return ans * (m - 2);
59         }
60 };
View Code

 

posted on 2014-03-26 20:32  yzcstc  阅读(143)  评论(0编辑  收藏  举报