A.Zeratu的军训游戏

Problems: 开灯问题,问无数次操作之后第n盏灯的状态

Analysis:

  cj:平方数有奇数个约数

Tags: Implementation

 

B.Zeratud的完美区间

Problems: 给定一个1..n的全排列,询问区间[l, r]中的数字是否排序后连续

Analysis:

   cj:智障的我想了一个及其错误的算法,后来被lucky_ji点醒,if (区间最大值最小值之差 == 区间长度)就好了。。

   Return:燃鹅楼上STILL犯了一个有趣的错误,Max-Min+1==Length,当然,区间Max和Min的维护用线段树或者倍增DP就行了

Tags: Data Structure, Dynamic Programming

 

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 //#include<iostream>
 5 #include<cmath>
 6 #include<queue>
 7 #include<map>
 8 #include<string>
 9 #include<vector>
10 using namespace std;
11 #define INF 2000000000
12 #define Clear(x, Num) memset(x, Num, sizeof(x))
13 #define Dig(x) ((x>='0') && (x<='9'))
14 #define Neg(x) (x=='-')
15 #define G_c() getchar()
16 #define Maxn 100010
17 typedef long long ll;
18  
19 int n, a[Maxn], D_min[Maxn][20], D_max[Maxn][20], m, l, r;
20  
21 inline int gcd(int x, int y) { if (!y) return x; return gcd(y, x%y); }
22 inline void read(int &x){ char ch; int N=1; while ((ch=G_c()) && (!Dig(ch)) && (!Neg(ch))); if (Neg(ch)) { N=-1; while ((ch=G_c()) && (!Dig(ch))); } x=ch-48; while ((ch=G_c()) && (Dig(ch))) x=x*10+ch-48; x*=N; }
23 //inline void Insert(int u, int v) { To[Cnt]=v; Next[Cnt]=Head[u]; Head[u]=Cnt++; }
24  
25 void rmq_Min()
26 {
27     int temp=(int)(log((double)n)/log(2.0));
28     for(int i=0;i<n;i++) D_min[i][0]=a[i];
29     for(int j=1;j<=temp;j++)
30         for(int i=0;i<n;i++)
31             if(i+(1<<j)<=n) D_min[i][j]=min(D_min[i][j-1], D_min[i+(1<<(j-1))][j-1]);
32 }
33  
34 void rmq_Max()
35 {
36     int temp=(int)(log((double)n)/log(2.0));
37     for(int i=0;i<n;i++) D_max[i][0]=a[i];
38     for(int j=1;j<=temp;j++)
39         for(int i=0;i<n;i++)
40             if(i+(1<<j)<=n) D_max[i][j]=max(D_max[i][j-1], D_max[i+(1<<(j-1))][j-1]);
41 }
42  
43 int Minimum(int L, int H)
44 {
45     int k=(int)(log((double)H-L+1)/log(2.0));
46     return min(D_min[L][k],D_min[H-(1<<k)+1][k]);
47 }
48  
49 int Maximum(int L, int H)
50 {
51     int k=(int)(log((double)H-L+1)/log(2.0));
52     return max(D_max[L][k],D_max[H-(1<<k)+1][k]);
53 }
54  
55 int main()
56 {
57     read(n);
58     for (int i=0; i<n; i++) read(a[i]);
59     rmq_Min(); rmq_Max();
60     read(m);
61     for (int i=1; i<=m; i++)
62     {
63         read(l); read(r); l--; r--;
64         int Res=Maximum(l, r)-Minimum(l, r)+1;
65         if (Res==r-l+1) puts("YES"); else puts("NO");
66     }
67 }
Code By Return

 

C. ACM群日常禁言一万年

Problems: 秒数转换为xdays, hh/mm/ss

Analysis:

   Return:模拟,注意输出格式即可

Tags: Implementation

 

D.Zeratud与LCM

Problems: 构造长度为n的序列{a},使得LCM(a1, a2, ......, an) = a1 + a2 + ...... + an

Analysis:

  Return:首先想到找规律,发现n为奇数时每次在后面加上2*6^k, 3*6^k即可,然后在找n为偶数规律的时候发现,易得下列式子

       ∑(a_i)=Lcm(a_i) <=> 6*∑(a_i)=6*Lcm(a_i) <=> ∑(a_i*6)=6*Lcm(a_i) <=> 1+2+3+∑(a_i*6)(a_i≠1)=6*Lcm(a_i)

       从而发现递推通式,然而,本题坑点在于对a_i的限制,然后发现只有在n=20的时候会Max{a_i}>Limit,从而进一步寻找规律可过

Tags: Math

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 //#include<iostream>
 5 #include<cmath>
 6 #include<queue>
 7 #include<map>
 8 #include<string>
 9 #include<vector>
10 using namespace std;
11 #define INF 2000000000
12 #define Clear(x, Num) memset(x, Num, sizeof(x))
13 #define Dig(x) ((x>='0') && (x<='9'))
14 #define Neg(x) (x=='-')
15 #define G_c() getchar()
16 #define Maxn 10010
17 typedef long long ll;
18  
19 int n, Cnt;
20 ll S[Maxn];
21  
22 inline int gcd(int x, int y) { if (!y) return x; return gcd(y, x%y); }
23 inline void read(int &x){ char ch; int N=1; while ((ch=G_c()) && (!Dig(ch)) && (!Neg(ch))); if (Neg(ch)) { N=-1; while ((ch=G_c()) && (!Dig(ch))); } x=ch-48; while ((ch=G_c()) && (Dig(ch))) x=x*10+ch-48; x*=N; }
24 //inline void Insert(int u, int v) { To[Cnt]=v; Next[Cnt]=Head[u]; Head[u]=Cnt++; }
25  
26 int main()
27 {
28     while (scanf("%d", &n)!=EOF)
29     {
30         if (n==3) { puts("3 2 1"); continue; }
31         S[1]=9, S[2]=6, S[3]=2, S[4]=1; Cnt=4;
32         while (Cnt<n)
33         {
34             for (int i=1; i<=Cnt; i++) if ((S[i]!=1) && (S[i]!=2)) S[i]*=2;
35             S[++Cnt]=3;
36         }
37         for (int i=1; i<=n; i++) printf("%lld ", S[i]); puts("");
38     }
39 }
Code By Return

 

E.小q与面试题

Problems: 维护一个可以查询最小值的栈

Analysis:

  cj: 这种题最适合用STL乱搞了

Tags: Data Structure

 

 1 #define PRON "e"
 2 #include <set>
 3 #include <stack>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <iostream>
 7 #include <algorithm>
 8 #define inf 0x3f3f3f3f
 9 using namespace std;
10 typedef long long ll;
11 
12 const int maxn = 500000 + 10;
13 
14 stack<int> q;
15 multiset<int> s;
16 
17 char ch;
18 inline void read(int & x){
19     int flag = 1;
20     do {
21         if (ch == '-')
22             flag = -1;
23         ch = getchar();
24     } while (!('0' <= ch && ch <= '9'));
25     
26     x = 0;
27     do {
28         x = x * 10 + ch - '0';
29         ch = getchar();
30     } while ('0' <= ch && ch <= '9');
31 
32     x *= flag;
33 }
34 
35 int main(){
36 #ifndef ONLINE_JUDGE
37     freopen(PRON ".in", "r", stdin);
38 #endif
39     s.clear();
40     while (not q.empty())
41         q.pop();
42 
43 
44     int T, a, b, sum = 0;
45     read(T);
46     while (T --){
47         read(a);
48         if (a == 0){
49             read(b);
50             ++ sum;
51             s.insert(b);
52             q.push(b);
53         }
54         if (a == 1){
55             if (sum == 0)
56                 puts("ERROR!");
57             else
58                 printf("%d\n", q.top());
59         }
60         if (a == 2){
61             if (sum == 0)
62                 puts("ERROR!");
63             else
64                 printf("%d\n", *s.begin());
65         }
66         if (a == 3){
67             if (sum == 0)
68                 puts("ERROR!");
69             else {
70                 -- sum;
71                 s.erase(s.find(q.top()));
72                 q.pop();
73             }
74         }
75     }
76 }
77         
78     
Code by cj

 

F.Zeratu与QQ堂

Problems: 给定一张n*n的地图,并有m次操作,每次操作为放置炸弹(在砖块上放置视为无效操作),炸弹可以炸掉上下左右最近的砖块,输出最后剩余的砖块数

Analysis:

  cj: 直接模拟会Time Limit Exceeded,用row[i]存储第i行的砖块的j坐标,col[j]存储第j行砖块的i坐标。每一次放置炸弹成功后,二分找到前后和左右的砖块并且erase

Tags: Implementation

 

  1 #define PRON "f"
  2 #include <vector>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <iostream>
  6 #include <algorithm>
  7 using namespace std;
  8 typedef long long ll;
  9 
 10 #define lb lower_bound
 11 #define r(y, x) lb(row[y].begin(), row[y].end(), x)
 12 #define c(x, y)    lb(col[x].begin(), col[x].end(), y)
 13 
 14 const int maxn = 1000 + 10;
 15 
 16 int n, sum = 0;
 17 char s[maxn][maxn];
 18 vector<int> row[maxn], col[maxn];
 19 
 20 int main(){
 21 #ifndef ONLINE_JUDGE
 22     freopen(PRON ".in", "r", stdin);
 23 #endif
 24 
 25     scanf("%d", &n);
 26     for (int i = 0; i < n; i ++){
 27         scanf("%s", s[i]);
 28 
 29         for (int j = 0; j < n; j ++)
 30             if (s[i][j] == '*')
 31                 ++ sum;
 32     }
 33 
 34     for (int i = 0; i < n; i ++)
 35         for (int j = 0; j < n; j ++)
 36             if (s[i][j] == '*')
 37                 row[i].push_back(j);
 38 
 39     for (int j = 0; j < n; j ++)
 40         for (int i = 0; i < n; i ++)
 41             if (s[i][j] == '*')
 42                 col[j].push_back(i);
 43 
 44     int q, x, y, pos;
 45     scanf("%d", &q);
 46     while (q --){    
 47         scanf("%d %d", &y, &x);
 48 
 49         if ((not row[y].empty() && *(r(y, x)) == x) && (not col[x].empty() && *(c(x, y)) == y))
 50             continue;
 51 
 52         if (not row[y].empty()){
 53             -- sum;
 54             if (x < *row[y].begin()){
 55                 col[*row[y].begin()].erase(c(*row[y].begin(), y));
 56                 row[y].erase(row[y].begin());
 57             }
 58             else if (x > *(row[y].end() - 1)){
 59                 col[*(row[y].end() - 1)].erase(c(*(row[y].end() - 1), y));
 60                 row[y].erase(row[y].end() - 1);
 61             }
 62             else {
 63                 -- sum;
 64                 pos = r(y, x) - row[y].begin();
 65                 col[row[y][pos]].erase(c(row[y][pos], y));
 66                 col[row[y][pos - 1]].erase(c(row[y][pos - 1], y));
 67 
 68                 row[y].erase(pos + row[y].begin());
 69                 row[y].erase(pos - 1 + row[y].begin());
 70             }
 71         }
 72 
 73         if (not col[x].empty()){
 74             -- sum;
 75             if (y < *col[x].begin()){
 76                 row[*col[x].begin()].erase(r(*col[x].begin(), x));
 77                 col[x].erase(col[x].begin());
 78             }
 79             else if (y > *(col[x].end() - 1)){
 80                 row[*(col[x].end() - 1)].erase(r(*(col[x].end() - 1), x));
 81                 col[x].erase(col[x].end() - 1);
 82             }
 83             else {
 84                 -- sum;
 85                 pos = c(x, y) - col[x].begin();
 86                 row[col[x][pos]].erase(r(col[x][pos], x));
 87                 row[col[x][pos - 1]].erase(r(col[x][pos - 1], x));
 88 
 89                 col[x].erase(pos + col[x].begin());
 90                 col[x].erase(pos - 1 + col[x].begin());
 91             }
 92         }
 93 
 94     }
 95 
 96 
 97     printf("%d\n", sum);
 98 }
 99         
100     
Code by cj

 

G.Zeratu的最优路径

Problems: 题面描述同最基本的数字“正方形”问题

Tags: Dynamic Programming

Posted on 2016-11-29 09:03  Recluse_Team  阅读(175)  评论(0编辑  收藏  举报