2009 Multi-University Training Contest 1 - Host by TJU
2016-10-28 00:04
316 查看
【HDU2817】 - A sequence of numbers——快速幂+水题
Time Limit: 2000/1000 MS (Java/Others) | Memory Limit: 32768/32768 K (Java/Others) |
---|
Problem Description
Xinlv wrote some sequences on the paper a long time ago, they might be arithmetic or geometric sequences. The numbers are not very clear now, and only the first three numbers of each sequence are recognizable. Xinlv wants to know some numbers in these sequences, and he needs your help.Input
The first line contains an integer N, indicting that there are N sequences. Each of the following N lines contain four integers. The first three indicating the first three numbers of the sequence, and the last one is K, indicating that we want to know the K-th numbers of the sequence.You can assume 0 < K <= 10^9, and the other three numbers are in the range [0, 2^63). All the numbers of the sequences are integers. And the sequences are non-decreasing.
Output
Output one line for each test case, that is, the K-th number module (%) 200907.Sample Input
21 2 3 5
1 2 4 5
Sample Output
516
给你数列的前三项,求第k个数是多少?数列只有等差和等比两种情况。则分别判断和计算一下,可能会爆long long ,注意处理。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const LL Mod = 200907; int n; LL a[3],k; LL Pow(LL n,LL m) { LL ans = 1; while(m) { if(m&1) ans = (ans*n)%Mod; n = (n*n)%Mod; m>>=1; } return ans; } int main() { scanf("%d",&n); for(int i = 0;i<n;i++) { for(int i = 0;i<3;i++) scanf("%lld",&a[i]); scanf("%d",&k); LL ans; if(a[1]%a[0] == 0 && a[2]%a[1] == 0 && a[1]/a[0] == a[2]/a[1]) { LL q = a[1]/a[0]; LL st = Pow(q,k-1); a[0] %= Mod; ans = (a[0]*st)%Mod; } else { LL d = (a[1] -a[0])%Mod; d = ((k-1)*d)%Mod; ans = (a[0]%Mod+d)%Mod; } printf("%lld\n",ans); } return 0; }
【HDU2818】-Building Block——并查集
Time Limit: 2000/1000 MS (Java/Others) | Memory Limit: 32768/32768 K (Java/Others) |
---|
Problem Description
John are playing with blocks. There are N blocks (1 <= N <= 30000) numbered 1…N。Initially, there are N piles, and each pile contains one block. Then John do some operations P times (1 <= P <= 1000000). There are two kinds of operation:M X Y : Put the whole pile containing block X up to the pile containing Y. If X and Y are in the same pile, just ignore this command.
C X : Count the number of blocks under block X
You are request to find out the output for each C operation.
Input
The first line contains integer P. Then P lines follow, each of which contain an operation describe above.Output
Output the count for each C operations in one line.Sample Input
6M 1 6
C 1
M 2 4
M 2 6
C 3
C 4
Sample Output
10
2
给你一些石子,有两种操作,一种将某一个编号的石子所在的石碓放在另一个编号的石碓上面,另一个操作是询问某一编号的石子下面有多少个石子。并查集的简单应用,每个石子维护两个信息,一个是自己所在石碓的石子的数量,一个是自己下面石子的数量。
#include <bits/stdc++.h> using namespace std; const int maxn = 30100; int pre[maxn]; int sum[maxn]; int num[maxn]; int Find(int x) { if(pre[x] == x) { return x; } else { int Fa = pre[x]; int s = Find(Fa); sum[x]+=sum[Fa]; pre[x] = s; return s; } } void Union(int x,int y) { int Fx = Find(x); int Fy = Find(y); if(Fx!=Fy) { sum[Fx] = num[Fy]; num[Fy] += num[Fx]; pre[Fx] = Fy; } } int main(){ int m; char op[2]; int u,v; while(~scanf("%d",&m)) { for(int i = 0;i<maxn;i++) pre[i] = i,num[i] = 1,sum[i] = 0; while(m--) { scanf("%s",op); if(op[0] == 'M') { scanf("%d %d",&u,&v); Union(u,v); } else { scanf("%d",&u); Find(u); printf("%d\n",sum[u]); } } } return 0; }
【HDU2819】-Swap——二分图
Time Limit: 2000/1000 MS (Java/Others) | Memory Limit: 32768/32768 K (Java/Others) |
---|
Problem Description
Given an N*N matrix with each entry equal to 0 or 1. You can swap any two rows or any two columns. Can you find a way to make all the diagonal entries equal to 1?Input
There are several test cases in the input. The first line of each test case is an integer N (1 <= N <= 100). Then N lines follow, each contains N numbers (0 or 1), separating by space, indicating the N*N matrix.Output
For each test case, the first line contain the number of swaps M. Then M lines follow, whose format is “R a b” or “C a b”, indicating swapping the row a and row b, or swapping the column a and column b. (1 <= a, b <= N). Any correct answer will be accepted, but M should be more than 1000.If it is impossible to make all the diagonal entries equal to 1, output only one one containing “-1”.
Sample Input
20 1
1 0
2
1 0
1 0
Sample Output
1R 1 2
-1
给你一个n*n的矩阵,问是否能够经过一些行的交换或者列的交换使得主对角线为1。对于一行都有对应的交换的列,那么就相当于每一行和对应的列进行匹配。转化为二分图的问题
#include <bits/stdc++.h> using namespace std; const int maxn = 110; int n; int G[maxn][maxn]; int row[maxn]; bool vis[maxn]; int dfs(int s) { for(int i = 1; i<=n; i++) { if(G[s][i] && !vis[i]) { vis[i] = true; if(!row[i] || dfs(row[i])) { row[i] = s; return 1; } } } return 0; } vector<pair<int,int> >vi; int main() { while(~scanf("%d",&n)) { for(int i = 1; i<=n; i++) { for(int j = 1; j<=n; j++) scanf("%d",&G[i][j]); } memset(row,0,sizeof(row)); int ans = 0; for(int i = 1; i<=n; i++) { memset(vis,false,sizeof(vis)); ans+=dfs(i); } if(ans<n) { printf("-1\n"); } else { vi.clear(); for(int i = 1; i<=n; i++) { int j =1; for(; j<=n&&row[j]!=i; j++); if(i==j)continue; vi.push_back(make_pair(i,j)); swap(row[i],row[j]); } printf("%d\n",vi.size()); for(int i = 0; i<vi.size(); i++) printf("C %d %d\n",vi[i].first,vi[i].second); } } return 0; }
【HDU2822】-Dogs——优先队列
Time Limit: 2000/1000 MS (Java/Others) | Memory Limit: 32768/32768 K (Java/Others) |
---|
Problem Description
Prairie dog comes again! Someday one little prairie dog Tim wants to visit one of his friends on the farmland, but he is as lazy as his friend (who required Tim to come to his place instead of going to Tim’s), So he turn to you for help to point out how could him dig as less as he could.We know the farmland is divided into a grid, and some of the lattices form houses, where many little dogs live in. If the lattices connect to each other in any case, they belong to the same house. Then the little Tim start from his home located at (x0, y0) aim at his friend’s home ( x1, y1 ). During the journey, he must walk through a lot of lattices, when in a house he can just walk through without digging, but he must dig some distance to reach another house. The farmland will be as big as 1000 * 1000, and the up left corner is labeled as ( 1, 1 ).
Input
The input is divided into blocks. The first line in each block contains two integers: the length m of the farmland, the width n of the farmland (m, n ≤ 1000). The next lines contain m rows and each row have n letters, with ‘X’ stands for the lattices of house, and ‘.’ stands for the empty land. The following two lines is the start and end places’ coordinates, we guarantee that they are located at ‘X’. There will be a blank line between every test case. The block where both two numbers in the first line are equal to zero denotes the end of the input.Output
For each case you should just output a line which contains only one integer, which is the number of minimal lattices Tim must dig.Sample Input
6 6..X…
XXX.X.
….X.
X…..
X…..
X.X…
3 5
6 3
0 0
Sample Output
3Hint
Hint: Three lattices Tim should dig: ( 2, 4 ), ( 3, 1 ), ( 6, 2 ).给你一个图,有起点和终点,问从起点到终点的经过最少’.’。
#include <bits/stdc++.h> #define PII pair<int,int> using namespace std; const int INF = 0x3f3f3f3f; int n,m; char str[1100][1100]; int x,y,x2,y2; int dir[][2] = {{1,0},{-1,0},{0,1},{0,-1}}; bool vis[1100][1100]; int dis[1100][1100]; bool ok(int x,int y) { return (x>=0&&x<n&&y>=0&&y<m); } struct node { int x,y,step; node(){} node(int _x,int _y,int _step):x(_x),y(_y),step(_step){} bool operator < (const node &a)const { return step > a.step; } }; int bfs() { memset(vis,false,sizeof(vis)); memset(dis,INF,sizeof(dis)); priority_queue<node>Q; dis[x][y] = 0; vis[x][y] = true; Q.push(node(x,y,0)); while(!Q.empty()) { node u = Q.top(); Q.pop(); node v; vis[u.x][u.y] = false; for(int i = 0;i<4;i++) { v.x = u.x + dir[i][0]; v.y = u.y + dir[i][1]; if(ok(v.x,v.y)) { int st = str[v.x][v.y] == 'X'?0:1; if(dis[v.x][v.y] > dis[u.x][u.y]+st) { dis[v.x][v.y] = dis[u.x][u.y]+st; v.step = u.step+st; if(!vis[v.x][v.y]) { vis[v.x][v.y] = true; Q.push(v); } } } } } return dis[x2][y2]; } int main(){ while(~scanf("%d %d",&n,&m)&&(n+m)) { for(int i = 0 ;i<n;i++) { scanf("%s",str[i]); } scanf("%d %d %d %d",&x,&y,&x2,&y2); x--;y--;x2--;y2--; int ans = bfs(); printf("%d\n",ans); } return 0; }
【HDU2824】-The Euler function——欧拉数
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) |
---|
Problem Description
The Euler function phi is an important kind of function in number theory, (n) represents the amount of the numbers which are smaller than n and coprime to n, and this function has a lot of beautiful characteristics. Here comes a very easy question: suppose you are given a, b, try to calculate (a)+ (a+1)+….+ (b)Input
There are several test cases. Each line has two integers a, b (2Output
Output the result of (a)+ (a+1)+….+ (b)Sample Input
3 100Sample Output
3042#include <bits/stdc++.h> using namespace std; typedef long long LL; const int maxn = 3000001; LL sum[maxn]; void GetPhi() { sum[1] = 1; for(int i = 2;i<maxn;i++) { if(!sum[i]) { for(int j = i;j<maxn;j+=i) { if(!sum[j]) sum[j] = j; sum[j] = sum[j]/i*(i-1); } } sum[i]+=sum[i-1]; } } int main(){ GetPhi(); int a,b; while(~scanf("%d %d",&a,&b)) { printf("%lld\n",sum-sum[a-1]); } return 0; }
【HDu2825】-Wireless Password——AC自动机+状态压缩
Time Limit: 2000/1000 MS (Java/Others) | Memory Limit: 32768/32768 K (Java/Others) |
---|
Problem Description
Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless network in the building. Liyuan did not know the password of the network, but he got some important information from his neighbor. He knew the password consists only of lowercase letters ‘a’-‘z’, and he knew the length of the password. Furthermore, he got a magic word set, and his neighbor told him that the password included at least k words of the magic word set (the k words in the password possibly overlapping).For instance, say that you know that the password is 3 characters long, and the magic word set includes ‘she’ and ‘he’. Then the possible password is only ‘she’.
Liyuan wants to know whether the information is enough to reduce the number of possible passwords. To answer this, please help him write a program that determines the number of possible passwords.
Input
There will be several data sets. Each data set will begin with a line with three integers n m k. n is the length of the password (1<=n<=25), m is the number of the words in the magic word set(0<=m<=10), and the number k denotes that the password included at least k words of the magic set. This is followed by m lines, each containing a word of the magic set, each word consists of between 1 and 10 lowercase letters ‘a’-‘z’. End of input will be marked by a line with n=0 m=0 k=0, which should not be processed.Output
For each test case, please output the number of possible passwords MOD 20090717.Sample Input
10 2 2hello
world
4 1 1
icpc
10 0 0
0 0 0
Sample Output
21
14195065
[b]给你m个串,问组成长度为n的串中有k个所给串的方案数
我们定义dp[i][j][k]表示长度为i,在自动机j个节点,个数为k的方案数,其中k由于最大有1-个所以可以状态压缩。
#include <bits/stdc++.h> using namespace std; const int mod = 20090717; const int maxn = 120; typedef long long LL; int tr[maxn][26],top; int fail[maxn]; char str[maxn]; int n,m,k; int flag[maxn]; int dp[26][maxn][1<<10]; void Insert(int Index) { int len = strlen(str); int x = 0 ; for(int i = 0; i<len; i++) { int st = str[i] - 'a'; if(!tr[x][st]) tr[x][st] = ++top; x = tr[x][st]; } flag[x] |= 1<<Index; } void GetFail() { memset(fail,0,sizeof(fail)); queue<int>Q; for(int i = 0; i<26; i++ ) if(tr[0][i]) Q.push(tr[0][i]); while(!Q.empty()) { int u = Q.front(); Q.pop(); for(int i = 0; i<26; i++) { if(tr[u][i]) { Q.push(tr[u][i]); fail[tr[u][i]] = tr[fail[u]][i]; flag[tr[u][i]] |= flag[tr[fail[u]][i]]; } else tr[u][i] = tr[fail[u]][i]; } } } int cnt(int s) { int ans = 0; for(int i = 0; i<m; i++) if((s>>i)&1) ans++; return ans; } int main() { while(~scanf("%d %d %d",&n,&m,&k)&&(n||m||k)) { memset(tr,0,sizeof(tr)); memset(flag,0,sizeof(flag)); top = 0; for(int i = 0; i<m; i++) { scanf("%s",str); Insert(i); } GetFail(); memset(dp,0,sizeof(dp)); dp[0][0][0] = 1; for(int i = 0; i<n; i++) { for(int j = 0; j<=top; j++) { for(int s = 0; s<(1<<m); s++) { if(dp[i][j][s] ==0 )continue; for(int t = 0; t<26; t++) (dp[i+1][tr[j][t]][s|flag[tr[j][t]]] +=dp[i][j][s])%=mod; } } } int ans = 0; for(int i = 0; i<=top; i++) { for(int j = 0; j<(1<<m); j++) { if(cnt(j)< k) continue; (ans+=dp [i][j])%=mod; } } printf("%d\n",ans); } return 0; }
相关文章推荐
- Wireless Password [ 2009 Multi-University Training Contest 1 - Host by TJU ]
- HDU3998 Sequence 动态规划+最大流2011 Multi-University Training Contest 16 - Host by TJU
- hdu 3094 A tree game 2009 Multi-University Training Contest 18 - Host by ECNU
- 2009 Multi-University Training Contest 8 - Host by BJNU
- Connections between cities&&2009 Multi-University Training Contest 8 - Host by BJNU
- HDU 3015——Disharmony Trees(树状数组 2009 Multi-University Training Contest 12 - Host by FZU)
- 2009 Multi-University Training Contest 5 - Host by NUDT
- 2009 Multi-University Training Contest 10 - Host by NIT
- 2009 Multi-University Training Contest 4 - Host by HDU
- hdu2888Check Corners【二维RMQ】2009 Multi-University Training Contest 9 - Host by HIT
- HDU3996 Gold Mine最大权闭合图 2011 Multi-University Training Contest 16 - Host by TJU
- HDU 3829 Cat VS Dog 2011 Multi-University Training Contest 1 - Host by HNU
- 2011 Multi-University Training Contest 1 - Host by HNU&&Cat VS Dog
- HDU3836 Equivalent Sets 2011 Multi-University Training Contest 1 - Host by HNU
- HDU 3902 Swordsman 2011 Multi-University Training Contest 7 - Host by ECNU 计算几何
- HDU 3911 Black And White 2011 Multi-University Training Contest 8 - Host by HUST 线段树应用
- hdu3832(2011 Multi-University Training Contest 1 - Host by HNU )
- Moonfang's Birthday&&2011 Multi-University Training Contest 3 - Host by BIT
- HDU HDU 3861 The King’s Problem 2011 Multi-University Training Contest 3 - Host by BIT
- HDU 3920 Clear All of Them I 状态压缩DP 2011 Multi-University Training Contest 9 - Host by BJTU