【补】【FZU月赛】【20150515】【待续】

Posted on 2015-05-19 12:08  LLGemini  阅读(151)  评论(0编辑  收藏  举报

A FZU-2054

水题,比较A,B双方的最大值即可。

B FZU-2055

string,截取‘.’之前和之后然后和给出的文件夹名和拓展名比较就好了啊,不明白为什么那么多人错。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<string>
 6 #include<algorithm>
 7 using namespace std;
 8 typedef long long LL;
 9 const int maxn = 100100;
10 string path[maxn], type[maxn];
11 int main()
12 {
13     int T; scanf("%d", &T);
14     while(T--)
15     {
16         int n, m; scanf("%d%d", &n, &m);
17         string str;
18         for(int i = 0; i < n; i++)
19         {
20             cin >> str;
21             int pos = str.find_last_of('.');
22             path[i] = str.substr(0, pos);
23             type[i] = str.substr(pos);
24         }
25         string t1, t2;
26         for(int i = 0; i < m; i++)
27         {
28             cin >> t1 >> t2;
29             for(int j = 0; j < n; j++)
30             {
31                 if(t2 != type[j]) continue;
32                 if(t1.length() > path[j].length()) continue;
33                 string tmp =  path[j].substr(0, t1.length());
34                 if(tmp == t1) {cout << path[j] << type[j] << endl;}
35             }
36         }
37 
38     }
39     return 0;
40 }
View Code

C FZU-2056

题意:现在有一个n*m的矩阵A,在A中找一个H*H的正方形,使得其面积最大且该正方形元素的和不大于 limit。

分析:开始以为是DP或者二维RMQ,其实用二分就可以做出来;

   在输入时构造元素和矩阵dp[][](即dp[i][j]为从(1,1)到(i,j)的矩形范围元素和);再在(0,min(m,n))范围内二分查找满足条件的最优解H;

   计算正方形内元素和的方法要掌握;

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 using namespace std;
 6 const int maxn = 1010;
 7 int m, n, lim;
 8 int dp[maxn][maxn];
 9 bool solve(int h)
10 {
11    // if(h == 1) return
12     for(int i = h; i <= n; i++)
13     {
14         for(int j = h; j <= m; j++)
15         {
16             if(dp[i][j]-dp[i-h][j]-dp[i][j-h]+dp[i-h][j-h] > lim) continue;
17             return true;
18         }
19     }
20     return false;
21 }
22 int main()
23 {
24     int T; scanf("%d", &T);
25     while(T--)
26     {
27         scanf("%d%d%d", &n, &m, &lim);
28         memset(dp, 0, sizeof(dp));
29         for(int i = 1; i <= n; i++)
30         {
31             int tmp = 0;
32             for(int j = 1; j <= m; j++)
33             {
34                 int x; scanf("%d", &x);
35                 tmp += x;
36                 dp[i][j] = dp[i-1][j]+tmp;
37             }
38         }
39 
40         int H = min(n, m);
41         int L = 0, R = H;
42         int M;
43         while(L < R)
44         {
45             M = L+(R-L)/2;
46             if(M == L) M++;
47             if(solve(M)) L = M;
48             else R = M-1;
49         }
50         cout << L*L << endl;
51     }
52     return 0;
53 }
View Code

D FZU-2057

题意:给出一树状家谱图,再给出两个人,问两人什么关系;

分析:又想复杂了,只要在输入时记录下父子母子关系,性别,然后由长辈往下搜就行,如果是男的就输出'F',女的输出‘M’,搜不到时注意改变长幼关系再搜一次,如果还搜不到就输出Relative;

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<queue>
 6 #include<stack>
 7 using namespace std;
 8 const int maxn = 10010;
 9 int vis[maxn], child[maxn], sex[maxn];
10 stack<int> vv;
11 struct Node
12 {
13     int f, m, sex;
14     bool operator == (const Node& rhs) const
15     {
16         return f==rhs.f && m == rhs.m;
17     }
18 }nodes[maxn];
19 void print()
20 {
21     while(!vv.empty()){
22         int t = vv.top(); vv.pop();
23         if(t == 1) printf("F");
24         else if(t == 2)printf("M");
25     }
26     printf("\n");
27 }
28 bool dfs(int u, int v)
29 {
30     while(!vv.empty()) vv.pop();
31     while(u != v)
32     {
33         if(sex[u] == 1)
34             vv.push(1);
35         else if(sex[u] == 2)
36             vv.push(2);
37         else
38             break;
39         u = child[u];
40     }
41     if(u == v)
42         return true;
43     else return false;
44 }
45 
46 int main()
47 {
48     int T; scanf("%d", &T);
49     while(T--)
50     {
51         memset(sex, 0, sizeof(sex));
52         int n; scanf("%d", &n);
53         int a, b, c;
54         for(int i = 0; i<n/2; i++)
55         {
56             scanf("%d%d%d", &a, &b, &c);
57 //            nodes[a].f = b, nodes[a].m = c;
58             sex[b] = 1, sex[c] = 2;
59             child[b] = child[c] = a;
60         }
61         int m; scanf("%d", &m);
62         while(m--)
63         {
64             int x, y; scanf("%d%d", &x, &y);
65             if(dfs(x, y))
66             {
67                 printf("0 ");
68                 print();
69             }
70             else if(dfs(y, x))
71             {
72                 printf("1 ");
73                 print();
74             }
75             else
76                 printf("Relative\n");
77         }
78     }
79     return 0;
80 }
View Code

E FZU-2058

题意:给出N个元素,问有多少对元素的和是M;

分析:一种常见的简单思路题;二层循环不用想肯定超时,dp当然也用不上,对于其中一个元素x,排序后用二分或者lower_bound/upper_bound函数搜索M-x的个数就好啦。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<queue>
 6 #include<stack>
 7 #include<algorithm>
 8 using namespace std;
 9 typedef long long LL;
10 const int maxn = 100100;
11 LL a[maxn];
12 LL n, m;
13 
14 LL solve()
15 {
16     LL cnt = 0;
17     for(int i = 0; i < n; i++)
18     {
19         LL t = m-a[i];
20         int pos1 = upper_bound(a+i+1, a+n, t)-a-i-1;
21         int pos2 = lower_bound(a+i+1, a+n, t)-a-i-1;
22         cnt += pos1-pos2;
23     }
24     return cnt;
25 }
26 
27 int main()
28 {
29 
30     while(~scanf("%I64d%I64d", &n, &m))
31     {
32         for(int i = 0; i < n; i++)
33         {
34             scanf("%I64d", &a[i]);
35         }
36         sort(a, a+n);
37         printf("%I64d\n", solve());
38     }
39 
40     return 0;
41 }
View Code

F FZU-2059

G FZU-2060

心好累,我再想想T ^ T;

I FZU-2062

题意:要想得到1~n之间的所有数,最少需要多少个数。

分析:确实是个有点意思的水题,前提是要想到十进制可以用二进制转换啊!愚蠢!不行得多练练位运算...

以n=5为例:

  5 = 1+2+2;

  4 = 2+2;

  3 = 1+2;

  2 = 2;

  1 = 1;

答案:log2(n)

J FZU-1859

题意:画图题,HDU2083的简化,递归画图就行;当然也有找规律画出来的,且待我研究研究...

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<string>
 6 #include<cstring>
 7 #include<algorithm>
 8 using namespace std;
 9 typedef long long LL;
10 const int maxn = 1100;
11 
12 int pic[maxn][maxn];
13 
14 void print(int x, int y, int n)
15 {
16     if(n == 1) {pic[x][y] = '1'; return;}
17     print(x, y, n-1);
18     print(x+(1<<(n-2)), y, n-1);
19     print(x+(1<<(n-2)), y+(1<<(n-2)), n-1);
20 }
21 
22 int main()
23 {
24     int T; scanf("%d", &T);
25     while(T--)
26     {
27         memset(pic, 0, sizeof(pic));
28         int n; scanf("%d", &n);
29         print(1, 1, n);
30         for(int i = 1; i <= (1<<(n-1)); i++)
31         {
32              for(int j = 1; j <= i; j++)
33                 if(pic[i][j]) printf("@"); else printf(" ");
34             printf("\n");
35         }
36     }
37 
38     return 0;
39 }
View Code

K FZU-1862

题意:给出一个环,按顺时针的顺序求出下标为L,R之间的最大的数;

分析:这题感觉时间上自己是水过去的,把环变成数组先打表求出各区间的最大值,然后输出即可。灰常简单的转化技巧。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<string>
 6 #include<cstring>
 7 #include<algorithm>
 8 using namespace std;
 9 typedef long long LL;
10 const int maxn = 2200;
11 int m[maxn], Max[maxn][maxn];
12 int main()
13 {
14     int n;
15     int kase = 0;
16     while(~scanf("%d", &n))
17     {
18         printf("Case #%d:\n", ++kase);
19         for(int i = 1; i <= n; i++) scanf("%d", &m[i]);
20         for(int i = 1; i <= n; i++) m[n+i] = m[i];
21         memset(Max, -1, sizeof(Max));
22         for(int i = 1; i <= n; i++)
23         {
24             for(int j = i; j <= n+i; j++)
25             {
26                 Max[i][j] = max(Max[i][j-1], m[j]);
27             }
28         }
29         int q; scanf("%d", &q);
30         for(int i = 0; i < q; i++)
31         {
32             int a, b; scanf("%d%d", &a, &b);
33             if(a <= b) printf("%d\n", Max[a][b]);
34             else printf("%d\n", Max[a][b+n]);
35         }
36         printf("\n");
37     }
38     return 0;
39 }
View Code