江西理工摸底测试

A题:water:

一开始写的时候,写超时了:一是有的条件没加上去,二是没有进行优化。

后来用了set将没有装满的瓶子的下标放进去,并进行排序,然后二分查找找后面比他大的下标。

我觉得这样的思路非常的ok,应该没毛病,但是就是老wa,原来在后面的循环没有赋初值。

下面是AC代码

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <set>
 5 
 6 using namespace std;
 7 const int ma = 1e5 + 10;
 8 int t,n,m;
 9 set<int> s;
10 struct node
11 {
12     int x,y;
13 }num[ma];
14 
15 int main()
16 {
17     scanf("%d",&t);
18     while(t--)
19     {
20         s.clear();
21         scanf("%d%d",&n,&m);
22         for(int i = 1;i <= n;i++)
23             scanf("%d",&num[i].x),s.insert(i),num[i].y=0;
24         int a,b,c;
25         while(m--)
26         {
27             scanf("%d%d",&a,&b);
28             c = min(num[a].x - num[a].y,b);
29             num[a].y += c;
30             b -= c;
31             if(num[a].x == num[a].y)
32                 s.erase(a);
33             set<int>::iterator it;
34             while(b > 0)
35             {
36                 it = s.lower_bound(a);
37                 if(it == s.end())
38                     break;
39                 a = *it;
40                 c = min(num[a].x - num[a].y,b);
41                 num[a].y += c;
42                 if(num[a].x == num[a].y)
43                     s.erase(a);
44                 b -= c;
45             }
46         }
47         for(int i = 1;i <= n;i++)
48             printf("%d%c",num[i].y," \n"[i==n]);
49     }
50     return 0;
51 }
View Code

后面发现还可以这样写:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <set>
 5 
 6 using namespace std;
 7 const int ma = 1e5 + 10;
 8 int t,n,m;
 9 set<int> s;
10 struct node
11 {
12     int x,y;
13 }num[ma];
14 
15 int main()
16 {
17     scanf("%d",&t);
18     while(t--)
19     {
20         s.clear();
21         scanf("%d%d",&n,&m);
22         for(int i = 1;i <= n;i++)
23             scanf("%d",&num[i].x),s.insert(i),num[i].y=0;
24         int a,b,c;
25         while(m--)
26         {
27             scanf("%d%d",&a,&b);
28             c = min(num[a].x - num[a].y,b);
29             num[a].y += c;
30             b -= c;
31             if(num[a].x == num[a].y)
32                 s.erase(a);
33             set<int>::iterator it;
34             while(b > 0)
35             {
36                 it = s.lower_bound(a);
37                 if(it == s.end())
38                     break;
39                 a = *it;
40                 c = min(num[a].x - num[a].y,b);
41                 num[a].y += c;
42                 if(num[a].x == num[a].y)
43                     s.erase(a);
44                 b -= c;
45             }
46         }
47         for(int i = 1;i <= n;i++)
48             printf("%d%c",num[i].y," \n"[i==n]);
49     }
50     return 0;
51 }
View Code

B题:题意是讲一个数分成三个素数的和,问有多少种分法?

首先肯定是先将n内的素数判断出来,然后进行有技巧的暴力,划重点是有技巧的暴力。

我天真的认为可以将出现的三个素数记录下来,然后它们再次出现的时候,就跳过,然而还是不行。

比赛完之后知道了怎么更好的解决这个问题,控制下标再加上一点限制就可以了。

下面是AC代码:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <bits/stdc++.h>
 6 
 7 using namespace std;
 8 const int ma = 4e4 + 10;
 9 int n,m,cnt,prime[ma];
10 set<int> pr;
11 bool vis[ma];
12 
13 void prim(int maxx)
14 {
15     for(int i = 2; i <= maxx; i++)
16     {
17         if(!vis[i])
18             prime[++cnt] = i;
19         for(int j = 1; j <= cnt && i*prime[j] <= maxx; j++)
20         {
21             vis[i*prime[j]] = 1;
22             if(i % prime[j] == 0)
23                 break;
24         }
25     }
26 }
27 struct node
28 {
29     int x,y,z;
30 };
31 
32 int main()
33 {
34     int t;
35     scanf("%d",&t);
36     prim(40000);
37     node a;
38     int b,ans;
39     while(t--)
40     {
41         scanf("%d",&n);
42         ans = 0;
43         for(int i = 1; prime[i] <= n; i++)
44         {
45             for(int j = i; prime[j] <= n; j++)
46             {
47                 b = prime[i] + prime[j];
48                 if(b >= n)
49                     break;
50                 if(!vis[n - b])
51                 {
52                     if(n - b >= prime[j])
53                         ans++;
54                 }
55             }
56         }
57         printf("%d",ans);
58         if(t != 0)
59             printf("\n");
60     }
61     return 0;
62 }
View Code

C题:就是将点连起来的花费最少的是。

这个就要进行三次的排序:将x,y,z分别进行排序,然后用克鲁斯卡尔。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 #define  pai pair<int,int>
 8 const int ma = 2e5 + 10;
 9 int x[ma],y[ma],z[ma],father[ma];
10 pai pp[ma];
11 int n;
12 struct edge
13 {
14     int from,to,val;
15 } num[4*ma];
16 
17 bool cmp(pai a,pai b)
18 {
19     return a.first < b.first;
20 }
21 bool cmp1(edge a,edge b)
22 {
23     return a.val < b.val;
24 }
25 int find_f(int a)
26 {
27     return a == father[a] ? a : father[a] = find_f(father[a]);
28 }
29 
30 int main()
31 {
32     scanf("%d",&n);
33     for(int i = 1; i <= n; i++)
34     {
35         scanf("%d%d%d",&x[i],&y[i],&z[i]),father[i] = i;
36     }
37     for(int i = 1; i <= n; i++)
38         pp[i].first = x[i],pp[i].second = i;
39     sort(pp+1,pp+1+n,cmp);
40     int cnt = 0;
41     for(int i = 1; i < n; i++)
42     {
43         num[++cnt].from = pp[i].second;
44         num[cnt].to = pp[i+1].second;
45         num[cnt].val = abs(pp[i+1].first - pp[i].first);
46     }
47     for(int i = 1; i <= n; i++)
48         pp[i].first = y[i],pp[i].second = i;
49     sort(pp+1,pp+1+n,cmp);
50     for(int i = 1; i < n; i++)
51     {
52         num[++cnt].from = pp[i].second;
53         num[cnt].to = pp[i+1].second;
54         num[cnt].val = abs(pp[i+1].first - pp[i].first);
55     }
56     for(int i = 1; i <= n; i++)
57         pp[i].first = z[i],pp[i].second = i;
58     sort(pp+1,pp+n+1,cmp);
59     for(int i = 1; i < n; i++)
60     {
61         num[++cnt].from = pp[i].second;
62         num[cnt].to = pp[i+1].second;
63         num[cnt].val = abs(pp[i+1].first - pp[i].first);
64     }
65     sort(num+1,num+1+cnt,cmp1);
66     int nu = 1,fa,fb;
67     int ans = 0;
68 //    for(int i = 1; i <= cnt; i++)
69 //        cout<<num[i].from<<" "<<num[i].to<<" "<<num[i].val<<endl;
70     for(int i = 1; i <= cnt && nu <= n -1; i++)
71     {
72         fa = find_f(num[i].from),fb = find_f(num[i].to);
73         //cout<<fa<<" "<<fb<<endl;
74         if(fa != fb)
75         {
76             father[fa] = fb,ans += num[i].val,nu++;
77         }
78     }
79     cout<<ans<<endl;
80     return 0;
81 }
View Code

D题还没补;

E题是给出一个整数n,将其分解为若干个正整数之和,使得这些正整数的乘积x最大:

只要尽可能的分成3,如果不能分成3就分成2;

然后要扩欧求逆元就好了

 1 #include <iostream>
 2 #include <cstdio>
 3 
 4 using namespace std;
 5 const int ma = 100;
 6 typedef long long ll;
 7 ll x,y,num[ma];
 8 int n;
 9 
10 void exgcd(ll a,ll b)
11 {
12     if(!b)
13     {
14         x = 1,y = 0;
15         return ;
16     }
17     exgcd(b,a%b);
18     ll temp = x;
19     x = y;
20     y = temp - a / b * y;
21 }
22 int main()
23 {
24     scanf("%d",&n);
25     ll k = 1;
26     for(int i = 5;i <= 66;i += 3)
27     {
28         num[i] = 6 * k;
29         num[i+1] = 9 * k;
30         num[i+2] = 12 * k;
31         k *= 3;
32     }
33     exgcd(n,num[n]);
34     while(x < 0)
35         x += num[n];
36     x %= num[n];
37     cout<<x;
38     return 0;
39 }
看我

F题是一个线段树的题直接看代码

 1 #include <iostream>
 2 #include <cstdio>
 3 
 4 using namespace std;
 5 const int ma = 1e5 + 10;
 6 int tree[4*ma],lazy[4*ma];
 7 int n,m,ans;
 8 
 9 void pushdown(int rt,int l,int r)
10 {
11     lazy[2*rt] += lazy[rt];
12     lazy[2*rt+1] += lazy[rt];
13     int mid = (l + r)/2;
14     tree[2*rt] += lazy[rt]*(mid - l + 1);
15     tree[2*rt+1] +=lazy[rt]*(r-mid);
16     tree[2*rt] %= 2;
17     tree[2*rt+1] %= 2;
18     lazy[rt] = 0;
19 }
20 void update(int rt,int l,int r,int L,int R)
21 {
22     if(L <= l && r <= R)
23     {
24         lazy[rt] += 1;
25         tree[rt] +=(r - l + 1);
26         tree[rt] %= 2;
27         return ;
28     }
29     if(lazy[rt])
30         pushdown(rt,l,r);
31     int mid = (l+r)/2;
32     if(L <= mid)
33         update(2*rt,l,mid,L,R);
34     if(R > mid)
35         update(2*rt+1,mid+1,r,L,R);
36     tree[rt] = tree[2*rt]+tree[2*rt+1];
37     tree[rt] %= 2;
38 }
39 void query(int rt,int l,int r,int x)
40 {
41     if(l == r && l == x)
42     {
43         ans = tree[rt];
44         return ;
45     }
46     int mid = (l + r) / 2;
47     if(lazy[rt])
48         pushdown(rt,l,r);
49     if(x <= mid)
50         query(2*rt,l,mid,x);
51     else
52         query(2*rt+1,mid+1,r,x);
53 }
54 int main()
55 {
56     scanf("%d%d",&n,&m);
57     int a,b,c;
58     while(m--)
59     {
60         scanf("%d%d",&a,&b);
61         if(a == 1)
62         {
63             scanf("%d",&c);
64             update(1,1,n,b,c);
65         }
66         else
67         {
68             ans = 0;
69             query(1,1,n,b);
70             printf("%d\n",ans);
71         }
72     }
73     return 0;
74 }
¥¥¥

G题差不多补完了,但是还有一点,所以还是没有补完。

H题:这题我很尴尬,竟然用错的方法过了,还是第一个过的······,我觉得脑子有坑才会那样写。

它要跑三遍的bfs第一遍跑第一个地图求出它的最短路径,第二遍跑第二个图也求最短的路径,看是否相等,相等的话就跑第三遍第一个和第二图结合的图看它的最短路径是不是一样,一样就输出YES。

看代码:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <queue>
 6 
 7 using namespace std;
 8 const int ma = 5e2 + 10;
 9 char s1[ma][ma],ss[ma][ma];
10 char s2[ma][ma];
11 bool vis[ma][ma];
12 int fx[4] = {0,1,0,-1};
13 int fy[4] = {1,0,-1,0};
14 int n,m,f;
15 struct node
16 {
17     int x,y;
18     int val;
19 };
20 
21 int bfs(char s[ma][ma])
22 {
23     node a,b;
24     queue<node> q;
25     vis[0][0] = 1;
26     for(int i = 0; i < n; i++)
27         for(int j = 0; j < m; j++)
28             vis[i][j] = 0;
29     a.x = 0,a.y = 0,a.val = 0;
30     q.push(a);
31     while(!q.empty())
32     {
33         a = q.front();
34         q.pop();
35         int xx,yy;
36         for(int i = 0; i < 4; i++)
37         {
38             xx = a.x + fx[i];
39             yy = a.y + fy[i];
40             if(xx == n - 1 && yy == m-1)
41             {
42                 f++;
43                 return a.val + 1;
44             }
45             if(xx >= 0 && xx < n && yy >= 0&& yy < m && s[xx][yy] != '#' && !vis[xx][yy])
46             {
47                 vis[xx][yy] = 1;
48                 b.x = xx,b.y = yy,b.val = a.val + 1;
49                 q.push(b);
50             }
51         }
52     }
53     return 0;
54 }
55 int main()
56 {
57     scanf("%d%d",&n,&m);
58     for(int i = 0; i < n; i++)
59         scanf(" %s",s1+i);
60     for(int i = 0; i < n; i++)
61         scanf(" %s",ss+i);
62     for(int i = 0; i < n; i++)
63         for(int j = 0; j < m; j++)
64         {
65             if(s1[i][j] == '#' || ss[i][j] == '#')
66                 s2[i][j] = '#';
67             else
68                 s2[i][j] = '.';
69         }
70     vis[0][0] = 1;
71     int len = bfs(s1),len1 = bfs(ss),len2 = bfs(s2);
72     if(n == m && n == 1)
73     {
74         bool ff = 0;
75         for(int i = 0; i < n; i++)
76             for(int j = 0; j < m; j++)
77                 if(s1[i][j] != ss[i][j])
78                     ff = 1;
79         if(ff)
80             len = 2;
81         else
82             f = 3;
83     }
84     if(f == 3 && len == len1 && len1 == len2)
85         printf("YES");
86     else
87         printf("NO");
88     return 0;
89 }
View Code

最一道题

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <bits/stdc++.h>
 6 
 7 using namespace std;
 8 const int ma = 1e5 + 10;
 9 char s[ma];
10 int n;
11 
12 int main()
13 {
14     scanf("%s",&s);
15     int len = strlen(s);
16     len--;
17     for(int i = 0,j = len;i < j;i++,j--)
18     {
19         if(s[i] < s[j])
20             s[j] = s[i];
21         else
22             s[i] = s[j];
23     }
24     cout<<s;
25     return 0;
26 }
View Code

猜你喜欢

转载自www.cnblogs.com/d1s2y3/p/11967829.html
今日推荐