第一次打CF,很菜,A了三道水题,第四题好像是是数位DP,直接放弃了。rateing从初始的1500变成了1499,还是绿名,这就很尴尬。之后觉得后面的题目也没有想象的那么难(看通过人数)过两天吧剩下的五题给补上。
http://codeforces.com/contest/981
A:给你一个字符串S,求把这个字符串中的最长不回文子序列。
思路:
如果S不回文,那就是本身
如果S回文:
(1)如果S由一种字母构成,那么最长不回文子序列为空,因为无论删除多少个都是回文串。
(2)如果S不是上述情况,那么最长不回文就是S.size() - 1
证明:
1、如果S是偶数回文:s1 s2 ... sn sn ... s2 s1
只需要删掉最后的s1即可,变成:s1 s2 ... sn sn ... s2
如果还是回文串,则关于红色部分对称。可以逐渐推导出sn = sn-1 = sn-2 = .. = s2 = s1,那就不满足S不是同一字母构成的前提,所以得证
2、如果S是奇数回文:s1 s2 ... sn ... s2 s1
同理只需要删掉最后的s1即可,变成 s1 s2 ... sn-1 sn sn-1 ... s2
如果还是回文串,也有上述规律。
1 #include2 using namespace std; 3 typedef long long ll; 4 const int maxn = 1e6 + 10; 5 const int mod = 1e9 + 7; 6 const double eps = 1e-10; 7 int main() 8 { 9 string s, s1; 10 cin >> s; 11 for(int i = s.size() - 1; i >= 0; i--) 12 { 13 s1 += s[i]; 14 } 15 int ans; 16 if(s1 == s) 17 { 18 set<char>c; 19 for(int i = 0; i < s.size(); i++)c.insert(s[i]); 20 if(c.size() == 1)ans = 0; 21 else ans = s.size() - 1; 22 } 23 else ans = s.size(); 24 cout< endl; 25 return 0; 26 }
B:两个公司,每个公司产品编号为ai,价值为bi,给出两个公司的ai,bi,如何使得两个公司的ai各不相同,且bi之和最大。
用map存储最大值即可
1 #include2 using namespace std; 3 typedef long long ll; 4 const int maxn = 1e6 + 10; 5 const int mod = 1e9 + 7; 6 const double eps = 1e-10; 7 int n, m, x, y; 8 map<int, int>a; 9 int main() 10 { 11 cin >> n; 12 while(n--) 13 { 14 cin >> x >> y; 15 a[x] = max(a[x], y); 16 } 17 cin >> m; 18 while(m--) 19 { 20 cin >> x >> y; 21 a[x] = max(a[x], y); 22 } 23 map<int, int>::iterator it = a.begin(); 24 ll ans = 0; 25 for(; it != a.end(); it++) 26 { 27 // cout< first<<" "< 31 return 0; 32 }second< 28 ans += it->second; 29 } 30 cout< endl;
C:给出一棵树,问这棵树是不是可以分成多条道路,每条边只属于一条道路,每两条道路有一个公共点。输出每条道路的起点和终点(多组解的话任意一组即可)
首先判断什么样的结构满足上述条件。
(1)整棵树就是一条链。满足。
(2)整棵树类似于下图,满足。n-1个点和另一点相连,道路就是每条边。
还有一种情况:
除去红点,所有点的度数均为1或2。
第二种情况就是这种情况的特殊版本。
所以直接判断每个点的度数即可。
1 #include2 using namespace std; 3 typedef long long ll; 4 const int maxn = 1e5 + 10; 5 const int mod = 1e9 + 7; 6 const double eps = 1e-10; 7 int n, m, x, y; 8 int num[maxn]; 9 int main() 10 { 11 cin >> n; 12 for(int i = 0; i < n - 1; i++) 13 { 14 scanf("%d%d", &x, &y); 15 num[x]++, num[y]++; 16 } 17 int do1 = 0, do2 = 0; 18 for(int i = 1; i <= n; i++) 19 { 20 if(num[i] == 1)do1++; 21 if(num[i] == 2)do2++; 22 } 23 if(do1 + do2 == n)//情况1 24 { 25 int ans[2], tot = 0; 26 for(int i = 1; i <= n; i++) 27 if(num[i] == 1)ans[tot++] = i; 28 cout<<"Yes\n1\n"; 29 cout< 0]<<" "< 1]<<endl; 30 return 0; 31 } 32 if(do1 + do2 == n - 1)//情况2,3 33 { 34 vector<int>ans; 35 int id; 36 for(int i = 1; i <= n; i++) 37 if(num[i] == 1)ans.push_back(i); 38 else if(num[i] != 2)id = i; 39 cout<<"Yes\n"< endl; 40 for(int i = 0; i < ans.size(); i++) 41 cout< " "< endl; 42 return 0; 43 } 44 cout<<"No"<<endl; 45 return 0; 46 }