AmazingCounters.com

2015 Multi-University Training Contest 3

 

 

1002 / HDU  5317 RGCDQ

题目大意:定义f(n)为n素因子的种类数,比如12=3*2*2有2和3两类素因子,给定l r求max{f(i),f(j)} (l<=i<j<=r)

思路:关键就是,2*3*5*7*11*13*17=510510再乘19就爆了,所以f(n)小于等于7!!!只要记录,这7个数在这个区间里分别出现了多少次,然后暴力扫7个数组合的gcd的最大值即可

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define N 1000009
 5 #define maxn 2000009
 6 using namespace std;
 7 int gcd(int x,int y)
 8 {
 9     if(x==0)return y;
10     return gcd(y%x,x);
11 }
12 int visit[maxn],sum[maxn][8];
13 int main()
14 {
15     int t;
16     for(int i=2;i<=N;i++)
17     {
18         if(!visit[i])
19         {
20             visit[i]=1;
21             for(int j=2;j*i<=N;j++)
22             {
23                 visit[i*j]++;
24             }
25         }
26         for(int j = 1;j<=7;j++)sum[i][j]=sum[i-1][j];
27         sum[i][visit[i]]++;
28     }
29     scanf("%d",&t);
30     while(t--)
31     {
32         int l,r;
33         int vis[10]={0};
34         scanf("%d%d",&l,&r);
35         for(int i=1;i<=7;i++)
36         {
37             if(sum[r][i]-sum[l-1][i]==1)vis[i]=1;
38             else if(sum[r][i]-sum[l-1][i]>1)vis[i]=2;
39         //    printf("%d ",vis[i]);
40         }
41         //puts("");
42         int ans = 1;
43         for(int i=1;i<=7;i++)if(vis[i])
44         {
45             for(int j=1;j<i;j++)if(vis[j])
46             {
47                 ans = max(ans, gcd(i,j));
48             }
49         }
50         for(int i=1;i<=7;i++)if(vis[i]==2)
51         {
52             ans = max(ans , i);
53         }
54         printf("%d\n",ans);
55     }
56     return 0;
57 }
View Code

 

 

1004 /HDU 5319 Painter:
题目大意:给一个N行的矩形,每次可以按/方向刷蓝色,按\方向刷红色,两种颜色相遇时变成绿色,问最从一个空矩形开始最少刷多少次可以得到目标矩形

思路:直接模拟,遇到R就把一\行全部刷玩遇到B和G同理

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #define maxn 100
  5 #define ll long long
  6 #define LLD "%lld"
  7 using namespace std;
  8 int a[maxn],m,n;
  9 char ch[maxn][maxn];
 10 int work(int x,int y)
 11 {
 12     int tx = x, ty = y;
 13     if(ch[x][y]=='R')
 14     {
 15         while(x<=n && y<=m)
 16         {
 17             if(ch[x][y]=='R')
 18             {
 19                 ch[x][y]='.';
 20             }
 21             else if(ch[x][y]=='G')
 22             {
 23                 ch[x][y]='B';
 24             }
 25             else break;
 26             x++;
 27             y++;
 28         }
 29         x = tx-1;
 30         y = ty-1;
 31         while(x>=1 && y>=1)
 32         {
 33             if(ch[x][y]=='R')
 34             {
 35                 ch[x][y]='.';
 36             }
 37             else if(ch[x][y]=='G')
 38             {
 39                 ch[x][y]='B';
 40             }
 41             else break;
 42             x--;
 43             y--;
 44         }
 45         return 1;
 46     }
 47     if(ch[x][y]=='B')
 48     {
 49         while(x<=n && y>=1)
 50         {
 51             if(ch[x][y]=='B')
 52             {
 53                 ch[x][y]='.';
 54             }
 55             else if(ch[x][y]=='G')
 56             {
 57                 ch[x][y]='R';
 58             }
 59             else break;
 60             x++;
 61             y--;
 62         }
 63         x=tx-1;
 64         y = ty+1;
 65         while(x>=1 && y<=m)
 66         {
 67             if(ch[x][y]=='B')
 68             {
 69                 ch[x][y]='.';
 70             }
 71             else if(ch[x][y]=='G')
 72             {
 73                 ch[x][y]='R';
 74             }
 75             else break;
 76             x--;
 77             y++;
 78         }
 79         return 1;
 80     }
 81     if(ch[x][y]=='G')
 82     {
 83         while(x<=n && y<=m)
 84         {
 85             if(ch[x][y]=='R')
 86             {
 87                 ch[x][y]='.';
 88             }
 89             else if(ch[x][y]=='G')
 90             {
 91                 ch[x][y]='B';
 92             }
 93             else break;
 94             x++;
 95             y++;
 96         }
 97         x = tx-1;
 98         y = ty-1;
 99         while(x>=1 && y>=1)
100         {
101             if(ch[x][y]=='R')
102             {
103                 ch[x][y]='.';
104             }
105             else if(ch[x][y]=='G')
106             {
107                 ch[x][y]='B';
108             }
109             else break;
110             x--;
111             y--;
112         }
113         x=tx,y=ty;
114         while(x<=n && y>=1)
115         {
116             if(ch[x][y]=='B')
117             {
118                 ch[x][y]='.';
119             }
120             else if(ch[x][y]=='G')
121             {
122                 ch[x][y]='R';
123             }
124             else break;
125             x++;
126             y--;
127         }
128         x=tx-1;
129         y = ty+1;
130         while(x>=1 && y<=m)
131         {
132             if(ch[x][y]=='B')
133             {
134                 ch[x][y]='.';
135             }
136             else if(ch[x][y]=='G')
137             {
138                 ch[x][y]='R';
139             }
140             else break;
141             x--;
142             y++;
143         }
144         return 2;
145     }
146 }
147 int main()
148 {
149     int t;
150     scanf("%d",&t);
151     while(t--)
152     {
153         scanf("%d",&n);
154         for(int i=1;i<=n;i++)
155         {
156             scanf("%s",ch[i]+1);
157         }
158         m = strlen(ch[1]+1);
159         int ans =0;
160         for(int i=1;i<=n;i++)
161         {
162             for(int j=1;j<=m;j++)
163             {
164                 if(ch[i][j]!='.')
165                 {
166                     ans += work(i,j);
167                 }
168             }
169         }
170         printf("%d\n",ans);
171     }
172     return 0;
173 }
View Code

 

1008 /HDU 5323 Solve this interesting problem

题目大意:给定一个区间[l,r],问是否可能是线段树上的一个区间

思路:由于线段树除了最后一层,几乎是完全二叉数,所以树高很小,可以直接爆搜所有情况,注意这题很坑!r+(r-l)+1<ans 这个剪枝换成r+(r-l)+1<=ans就re 心中是千万条草你妈奔过啊

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define ll long long
 5 using namespace std;
 6 long long a,b,ans;
 7 void dfs(long long l,long long r)
 8 {
 9     if(l==0)
10     {
11         ans = min(ans,r);
12         return;
13     }
14     if(r > ans || r-l+1 > l)return;
15     if(l-1-(r-l)>=0)dfs(2*l-1-(r),r);
16     if(l-1-(r-l+1)>=0)dfs(l-1-(r-l+1),r);
17     if(r+(r-l)<ans)dfs(l,r+(r-l));
18     if(r+(r-l)+1<ans)dfs(l,r+(r-l)+1);
19 }
20 int main()
21 {
22     while(scanf("%lld%lld",&a,&b)!=EOF)
23     {
24         ans = 1LL<<59;
25         dfs(a,b);
26         if(ans!=1LL<<59)printf("%lld\n",ans);else puts("-1");
27     }
28     return 0;
29 }
View Code

 

 

1010 / HDU 5325 crazy bobo

题目大意:给一棵树,每个节点有个权值w,要找到一些点u1 u2 u3.......使得w[u1]<w[u2]<w[u3]..并且对于ui u(i+1)路径上不存在一个点X使得w[x]>=w[ui]
思路:有点玄学的题,比赛时想到先排序然后T了,比赛后想了想xiaoxin的并查集做法想到了一个更神奇的做法,从大到小排序,对于每个点找相邻点中形成最大的集合数,累加来更新自己这个点的最大集合数,TUT要是再等一等比赛能少TLE一发的

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define maxn 1000009
 6 #define ll long long
 7 #define LLD "%lld"
 8 using namespace std;
 9 struct T
10 {
11     int w;
12     int id;
13 }a[maxn];
14 int nex[maxn],point[maxn],head[maxn],b[maxn],ww[maxn];
15 int n,x,y,now,st[maxn],h,father[maxn],cnt[maxn];
16 int cmp(T a,T b)
17 {
18     return a.w<b.w;
19 }
20 void add(int x,int y)
21 {
22     nex[++now] = head[x];
23     head[x] = now;
24     point[now] = y;
25 }
26 int find(int x)
27 {
28     if(father[x]==x)return x;
29     return father[x] = find(father[x]);
30 }
31 int main()
32 {
33     while(scanf("%d",&n)!=EOF)
34     {
35         now = 0;
36         memset(head,0,sizeof(head));
37         for(int i=1;i<=n;i++)
38         {
39             father[i]=i;
40             cnt[i]=1;
41             scanf("%d",&a[i].w);
42             ww[i] = a[i].w;
43             a[i].id = i;
44         }
45         sort(a+1,a+1+n,cmp);
46         for(int i=1;i<n;i++)
47         {
48             scanf("%d%d",&x,&y);
49             add(x,y);
50             add(y,x);
51         }
52         int ans = 0;
53         for(int i=n;i>=1;i--)
54         {
55             int u = a[i].id,an=0;
56             for(int j = head[u];j;j=nex[j])
57             {
58                 int v = point[j];
59                 if(ww[v]>=ww[u])an+=b[v];
60             }
61             b[u] = an+1;
62             ans = max(b[u],ans);
63         }
64         printf("%d\n",ans);
65     }
66     return 0;
67 }
View Code

 

 

 

1011 / HDU 5326 work

题目大意:给一棵树,问你有多少点的子树正好有K个节点

思路:大水题,直接dfs即可

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define maxn 100009
 5 #define ll long long
 6 #define LLD "%lld"
 7 using namespace std;
 8 int nex[maxn],head[maxn],point[maxn],now,ans;
 9 int n,k,x,y,in[maxn];
10 void add(int x,int y)
11 {
12     nex[++now] = head[x];
13     head[x] = now;
14     point[now] = y;
15 }
16 int dfs(int x,int k)
17 {
18     int ret = 1;
19     for(int i=head[x];i;i=nex[i])
20     {
21         int u = point[i];
22         ret+=dfs(u,k);
23     }
24     if(ret-1==k)
25     {
26         ans++;
27     }
28     return ret;
29 }
30 int main()
31 {
32     int t;
33     while(scanf("%d%d",&n,&k)!=EOF)
34     {
35         now = 0 ;
36         memset(in,0,sizeof(in));
37         memset(head,0,sizeof(head));
38         for(int i=1;i<n;i++)
39         {
40             scanf("%d%d",&x,&y);
41             add(x,y);
42             in[y]++;
43         }
44         ans=0;
45         for(int i=1;i<=n;i++)if(in[i]==0)
46         {
47             dfs(i,k);
48         }
49         printf("%d\n",ans);
50     }
51     return 0;
52 }
View Code

 

posted @ 2015-07-28 20:17  philippica  阅读(302)  评论(0编辑  收藏  举报