题目链接:http://hihocoder.com/contest/hihointerview12
期末完事了,终于有时间成套刷题了。这套题比较简单,难度上感觉和上一套差不多。除了最后一个题是看了讨论版说数据水才敢写的。
A Word Construction
解法:正解应该是dfs+剪枝,我的思路是贪心,竟然过了。先把字符串按字典序排序,然后枚举每一个串作为起始,记下串内有什么字符,再从头到尾枚举所有字符串,看看每一个是否符合条件。就那么100个字符串,数据弱得很。
1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include <cassert> 8 #include <cstdio> 9 #include <cstdlib> 10 #include <bitset> 11 #include <vector> 12 #include <deque> 13 #include <queue> 14 #include <stack> 15 #include <ctime> 16 #include <set> 17 #include <map> 18 #include <cmath> 19 using namespace std; 20 #define fr first 21 #define sc second 22 #define cl clear 23 #define BUG puts("here!!!") 24 #define W(a) while(a--) 25 #define pb(a) push_back(a) 26 #define Rint(a) scanf("%d", &a) 27 #define Rll(a) scanf("%I64d", &a) 28 #define Rs(a) scanf("%s", a) 29 #define Cin(a) cin >> a 30 #define FRead() freopen("in", "r", stdin) 31 #define FWrite() freopen("out", "w", stdout) 32 #define Rep(i, len) for(int i = 0; i < (len); i++) 33 #define For(i, a, len) for(int i = (a); i < (len); i++) 34 #define Cls(a) memset((a), 0, sizeof(a)) 35 #define Clr(a, x) memset((a), (x), sizeof(a)) 36 #define Full(a) memset((a), 0x7f7f7f, sizeof(a)) 37 #define lrt rt << 1 38 #define rrt rt << 1 | 1 39 #define pi 3.14159265359 40 #define RT return 41 #define lowbit(x) x & (-x) 42 #define onenum(x) __builtin_popcount(x) 43 typedef long long LL; 44 typedef long double LD; 45 typedef unsigned long long ULL; 46 typedef pair<int, int> pii; 47 typedef pair<string, int> psi; 48 typedef pair<LL, LL> pll; 49 typedef map<string, int> msi; 50 typedef vector<int> vi; 51 typedef vector<LL> vl; 52 typedef vector<vl> vvl; 53 typedef vector<bool> vb; 54 55 const int maxn = 1000; 56 string s[maxn]; 57 int n; 58 int ascii[256]; 59 60 int main() { 61 // FRead(); 62 while(~Rint(n)) { 63 Rep(i, n) cin >> s[i]; 64 sort(s, s+n); 65 int ret = 0; 66 Rep(k, n) { 67 Cls(ascii); 68 Rep(j, s[k].length()) ascii[s[k][j]] = 1; 69 int cur = 1; 70 Rep(i, n) { 71 bool flag = 0; 72 Rep(j, s[i].length()) { 73 if(ascii[s[i][j]] == 1) { 74 flag = 1; 75 break; 76 } 77 } 78 if(flag == 0) { 79 Rep(j, s[i].length()) ascii[s[i][j]] = 1; 80 cur++; 81 } 82 } 83 ret = max(ret, cur); 84 } 85 printf("%d ", ret); 86 } 87 RT 0; 88 }
B Email Merge
解法:STL+并查集,这题很好想,但是写起来比较麻烦。对于字符串数组,想要做并查集操作的话,需要map<string, int>这样从字符串到整型的映射支持。读入数据按照邮箱为根节点,儿子是用户名,构建一个森林。这个时候同时更新并查集,也就是合并同一个树根下的所有用户名字符串。接着遍历所有用户名,扔到对应的belong中。我开的belong是堆,因为输出要求按照出现的顺序,所以堆序就是输入的顺序,也就是之前赋值的id号。
1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include <cassert> 8 #include <cstdio> 9 #include <cstdlib> 10 #include <bitset> 11 #include <vector> 12 #include <deque> 13 #include <queue> 14 #include <stack> 15 #include <ctime> 16 #include <set> 17 #include <map> 18 #include <cmath> 19 using namespace std; 20 #define fr first 21 #define sc second 22 #define cl clear 23 #define BUG puts("here!!!") 24 #define W(a) while(a--) 25 #define pb(a) push_back(a) 26 #define Rint(a) scanf("%d", &a) 27 #define Rll(a) scanf("%I64d", &a) 28 #define Rs(a) scanf("%s", a) 29 #define Cin(a) cin >> a 30 #define FRead() freopen("in", "r", stdin) 31 #define FWrite() freopen("out", "w", stdout) 32 #define Rep(i, len) for(int i = 0; i < (len); i++) 33 #define For(i, a, len) for(int i = (a); i < (len); i++) 34 #define Cls(a) memset((a), 0, sizeof(a)) 35 #define Clr(a, x) memset((a), (x), sizeof(a)) 36 #define Full(a) memset((a), 0x7f7f7f, sizeof(a)) 37 #define lrt rt << 1 38 #define rrt rt << 1 | 1 39 #define pi 3.14159265359 40 #define RT return 41 #define lowbit(x) x & (-x) 42 #define onenum(x) __builtin_popcount(x) 43 typedef long long LL; 44 typedef long double LD; 45 typedef unsigned long long ULL; 46 typedef pair<int, int> pii; 47 typedef pair<string, int> psi; 48 typedef pair<LL, LL> pll; 49 typedef map<string, int> msi; 50 typedef vector<int> vi; 51 typedef vector<LL> vl; 52 typedef vector<vl> vvl; 53 typedef vector<bool> vb; 54 55 const int maxn = 100010; 56 typedef struct Node { 57 string d; 58 int idx; 59 Node() { idx = -1; } 60 Node(string dd, int ii) : d(dd), idx(ii) {} 61 friend bool operator<(Node a, Node b) { return a.idx > b.idx; } 62 }Node; 63 64 string mail, user; 65 bool vis[maxn]; 66 map<string, int> id; 67 map<string, set<string> > wt; 68 priority_queue<Node> belong[100010]; 69 70 int n, m, cnt; 71 int pre[maxn]; 72 73 int find(int x) { 74 return x == pre[x] ? x : pre[x] = find(pre[x]); 75 } 76 77 void unite(int x, int y) { 78 x = find(x); y = find(y); 79 if(x < y) pre[y] = x; 80 else pre[x] = y; 81 } 82 83 int main() { 84 // FRead(); 85 cnt = 1;id.cl(); wt.cl(); Cls(vis); 86 Rint(n); 87 Rep(i, n*10) { 88 pre[i] = i; 89 while(!belong[i].empty()) belong[i].pop(); 90 } 91 Rep(i, n) { 92 cin >> user; 93 cin >> m; 94 id[user] = cnt++; 95 Rep(j, m) { 96 cin >> mail; 97 if(id.find(mail) == id.end()) id[mail] = cnt++; 98 wt[mail].insert(user); 99 unite(id[user], id[mail]); 100 } 101 } 102 map<string, set<string> >::iterator it; 103 set<string>::iterator each; 104 for(it = wt.begin(); it != wt.end(); it++) { 105 for(each = it->second.begin(); each != it->second.end(); each++) { 106 if(!vis[id[*each]]) { 107 vis[id[*each]] = 1; 108 belong[find(id[*each])].push(Node(*each, id[*each])); 109 } 110 } 111 } 112 Rep(i, cnt) { 113 if(!belong[i].empty()) { 114 while(!belong[i].empty()) { 115 cout << belong[i].top().d << " "; 116 belong[i].pop(); 117 } 118 cout << endl; 119 } 120 } 121 RT 0; 122 }
C Matrix Sum
解法:这题毒瘤题…数据里有负数,不同语言对负数取模运算的结果不一样,C++和Java是一个负数对一个正数取模是一个负数,而Python是正数。这题的正解应当是二维线段树or树状数组(树套树),分别维护自己列的值。而我直接维护前缀和了。写了各种语言的解法,改来改去最后改了java。
1 import java.lang.reflect.Array; 2 import java.util.Arrays; 3 import java.util.Comparator; 4 import java.util.Scanner; 5 6 import javax.swing.text.GapContent; 7 8 public class Main { 9 public static void main(String[] args) { 10 Scanner in = new Scanner(System.in); 11 int n, m; 12 int[][] dp = new int[1010][1010]; 13 String cmd = new String(); 14 for(int i = 0; i < 1010; i++) { 15 for(int j = 0; j < 1010; j++) { 16 dp[i][j] = 0; 17 } 18 } 19 n = in.nextInt(); m = in.nextInt(); 20 int x1, x2, y1, y2, num; 21 while(m-- > 0) { 22 cmd = in.next(); 23 if(cmd.charAt(0) == 'A') { 24 x1 = in.nextInt(); 25 y1 = in.nextInt(); 26 num = in.nextInt(); 27 for(int i = y1; i < n; i++) { 28 dp[x1][i] = (dp[x1][i] + num) % 1000000007; 29 } 30 } 31 else { 32 x1 = in.nextInt(); 33 x2 = in.nextInt(); 34 y1 = in.nextInt(); 35 y2 = in.nextInt(); 36 int ret = 0; 37 for(int i = x1; i <= y1; i++) { 38 if(x2 == 0) ret = (ret + dp[i][y2]) % 1000000007; 39 else ret = (ret + dp[i][y2] - dp[i][x2-1]) % 1000000007; 40 } 41 System.out.println((ret + 1000000007) % 1000000007); 42 } 43 } 44 } 45 }