Xeon 第一次训练赛 苏州大学ICPC集训队新生赛第二场(同步赛) [Cloned]
A.给出一个字符串,求出连续的权值递增和,断开以后权值重新计数,水题
#include<iostream> #include<string> #include<cmath> #include<cstring> #include<vector> #include<map> #include<set> #include<algorithm> #include<queue> #include<stack> #include<sstream> #include<cstdio> #define INF 0x3f3f3f3f //const int maxn = 1e6 + 5; const double PI = acos(-1.0); typedef long long ll; using namespace std; char s[85]; int main() { int T; int ans; int cnt; scanf("%d", &T); getchar(); while (T--) { ans = 0; cnt = 1; scanf("%s", s); for (int i = 0; i < strlen(s); i++) { if (s[i] != 'X') ans += cnt, cnt++; else cnt = 1; } printf("%d\n", ans); } return 0; }
B.给出四面体ABCD,起点由D开始走n步回到D,问有多少种不同的走法(中间可以再次经过D)
考虑DP枚举,复杂度O(n)
#include<cstdio> using namespace std; const int maxn = 1e7+5; const int mod = 1e9+7; int dp[maxn][4]; int n; int main(){ scanf("%d",&n); dp[1][0] = 0; dp[1][1] = dp[1][2] = dp[1][3] = 1; for (int i = 1; i <= n; i++){ for (int j = 0; j < 4; j++){ for (int k = 0; k < 4; k++){ if (j == k) continue; dp[i][j] += dp[i-1][k]; dp[i][j] %= mod; } } } printf("%d",dp[n][0]); return 0; }
C.给出数字a,b,求a的重新排列以后小于b的最大值
思维题,若|a|<|b|,显然只需将a降序排列即可,否则 方法是将a升序排列,每次确定最高位,最终结果就是最优解
#include<iostream> #include<string> #include<cmath> #include<cstring> #include<vector> #include<map> #include<set> #include<algorithm> #include<queue> #include<stack> #include<sstream> #include<cstdio> #define INF 0x3f3f3f3f const int maxn = 1e9 + 5; const double PI = acos(-1.0); typedef long long ll; using namespace std; string a; string b; string t; int main() { cin >> a >> b; int len1 = a.length(), len2 = b.length(); sort(a.begin(), a.end()); if (len1 < len2) reverse(a.begin(), a.end()); else { int l, r; for (l = 0; l < len1; l++) { r = len1 - 1; t = a; while (r > l) { swap(a[l], a[r--]); sort(a.begin()+l+1, a.end()); if (a > b) a = t; else break; } } } printf("%s", a.c_str()); return 0; }
G.从起点出发到目标点x,步数从1开始每次严格增加1,问最短步次可达x
仍然是思维题 首先显然的是x是负数无需考虑(对称性), 接下来考虑x在数轴右侧
首先考虑x无限大的情况,那显然前期的任何一步都是浪费的(物理思维?),事实上也是如此,往左走的步数显然是用于微调的
考虑到一直往左走第一次超越x,若此时del是偶数,那么显然可以在之前的第del/2步往左走,效果相当于往左走了del步,正好可达最优解
若del是奇数,那只需至多再走1,2步就能到偶数的情况
#include<iostream> #include<string> #include<cmath> #include<cstring> #include<vector> #include<map> #include<set> #include<algorithm> #include<queue> #include<stack> #include<sstream> #include<cstdio> #define INF 0x3f3f3f3f const int maxn = 1e9 + 5; const double PI = acos(-1.0); typedef long long ll; using namespace std; int ans[100005]; int main() { int i; for(i=1;;i++){ ans[i]=i*(i+1)/2; if(ans[i]>maxn) break; } int x; scanf("%d",&x); if(!x) { printf("0"); return 0; } if(x<0) x=-x; int p=lower_bound(ans,ans+i,x)-ans; int ret=ans[p]-x; while(ret&1) p++,ret+=p; int Ans=p; printf("%d",Ans); return 0; }
F.水题, 给定n个矩形,求一点的坐标,该点满足被k个矩形包含
#include<iostream> #include<string> #include<cmath> #include<cstring> #include<vector> #include<map> #include<set> #include<algorithm> #include<queue> #include<stack> #include<sstream> #include<cstdio> #define INF 0x3f3f3f3f const int maxn = 1e9 + 5; const double PI = acos(-1.0); typedef long long ll; using namespace std; int a[55]; int main() { int n, k; scanf("%d%d", &n, &k); if (k > n) { printf("-1"); return 0; } for (int i = 0; i < n; i++) scanf("%d", &a[i]); sort(a, a + n); printf("%d 0", a[n - k ]); return 0; }
D.数学+构造
考虑到题目给的提示“不超过n+1‘,说明答案应该和n有关,策略是先让每个数变成大数,然后依次取模,只要取模数是递减的,就能保证是递增的
#include<iostream> #include<string> #include<cmath> #include<cstring> #include<vector> #include<map> #include<set> #include<algorithm> #include<queue> #include<stack> #include<sstream> #include<cstdio> #define INF 0x3f3f3f3f //const int maxn = 1e9 + 5; const double PI = acos(-1.0); typedef long long ll; using namespace std; int maxn = 1e5+5000; int a[2005]; int main() { int n; scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); a[i] += maxn; } printf("%d\n", n + 1); printf("1 %d %d\n", n, maxn); for (int i = 1; i <= n; i++) { printf("2 %d %d\n", i, a[i] - i); } return 0; }