NOIP 2018普及组复赛C/C++参考答案

网友投稿 2019-05-18 17:54

第1题 标题统计 #include #include using namespace std; int main() { freopen("title.in", "r", stdin); freopen("title.out", "w", stdout); string title; getline(cin, title); int len = title.size(); for(int i = 0; i < (int)title.size(); i++) { if(' ' == title[i]) { len--; } } cout << len; return 0; } 评测结果 第2题 龙虎斗 #include #include #include using namespace std; #define LL long long int main() { freopen("fight.in","r",stdin); freopen("fight.out","w",stdout); int n, i, m, p1, p2; cin >> n; LL c[n + 1], s1, s2; for(i = 1; i <= n; i++) { cin >> c[i]; } cin >> m >> p1 >> s1 >> s2; c[p1] += s1; LL lPower = 0; // 龙势力 for(i = 1; i < m; i++) { lPower += c[i] * (m - i); } LL rPower = 0; for(i = m + 1; i <= n; i++) { rPower += c[i] * (i - m); } //cout << lPower << ' ' << rPower << endl; LL gap = abs(lPower - rPower); // 双方的气势差 p2 = m; //默认放在m位置 for(i = 1; i <= n; i++) { if(i < m) // 神兵加到左侧龙势力 { if(abs(lPower + s2 * (m - i) - rPower) < gap) { gap = abs(lPower + s2 * (m - i) - rPower); p2 = i; } } else if(i > m) // 神兵加到右侧虎势力 { if(abs(rPower + (i - m) * s2 - lPower) < gap) { gap = abs(rPower + (i - m) * s2 - lPower); p2 = i; } } } cout << p2 << endl; return 0; } 评测结果: 第3题 摆渡车 #include #include #include using namespace std; int n,m; int data[1024]; int sum[1024]; int dp[1024][128]; int main() { // freopen("bus.in", "r", stdin); // freopen("bus.out", "w", stdout); scanf("%d%d", &n, &m); for(int i=1; i<=n; ++i) { scanf("%d", data + i); } sort(data+1, data+n+1); for(int i=1; i<=n; ++i) { sum[i] = sum[i-1] + data[i]; } // i代表第i个人(可能不止一个) for(int i = 1; i <= n; ++i) { // j表示当前这个人可能的候车时间,取值[0,m-1) for(int j = 0; j < m; ++j) { int curBusTime=data[i] + j; if(j) { dp[i][j] = dp[i][j - 1]; } else { dp[i][j] = curBusTime*i - sum[i]; } // 最近的一趟车可能出发的时间 for(int lastBusTime = max(curBusTime - 2 * m + 1, 0); lastBusTime <= curBusTime - m; ++lastBusTime) { // lastCarry表示被上一辆车接走的学生人数 int lastCarry = lower_bound(data + 1, data + n + 1, lastBusTime + 1)- (data + 1); // lastWait表示上一个人的候车时间 int lastWait = min(lastBusTime - data[lastCarry], m - 1); // 动态转移方程 int tmp = dp[lastCarry][lastWait] + (i - lastCarry) * curBusTime - (sum[i] - sum[lastCarry]); if(tmp< p=""> { dp[i][j]=tmp; } } } } printf("%dn",dp[n][m-1]); return 0; } 评测结果 第4题 对称二叉树 #include inline int max(int x, int y) { return x > y ? x : y; } const int MAXN = 1000000; int cnt[MAXN + 5], lef[MAXN + 5], rig[MAXN + 5], ans; int v[MAXN + 5]; // 节点的权值 // 检查左右子树是否对称 bool checkSym(int leftId, int rightId) { if(leftId == -1 && rightId == -1) { // 若左右子节点都不存在,则认为是对称 return true; } if(v[leftId] != v[rightId]) { // 左子节点值 不等于 右子节点值,说明不对称 return false; } else { // 左子节点值等于右子节点值,则左左=右右且右左=左右,说明对称;否则不对称。注意要递归下去 return checkSym(lef[leftId], rig[rightId]) && checkSym(rig[leftId], lef[rightId]); } } // 求第nodeId个节点为根节点的二叉树,所包含的节点总数 int nodeCnt(int nodeId) { // 当前节点不存在 if(-1 == nodeId) { return 0; } else { // 左子树节点数 + 右子树节点树 + root本身的节点数1 return cnt[nodeId] = nodeCnt(lef[nodeId]) + nodeCnt(rig[nodeId]) + 1; } } void dfs(int nodeId) { // 空节点为递归终止的条件 if(-1 == nodeId) { return; } // 左子树节点总数 等于 右子树节点总数,这是对称的前提 if(cnt[lef[nodeId]] == cnt[rig[nodeId]]) { if(checkSym(lef[nodeId], rig[nodeId])) { // 若对称,获取总的节点数,并与原先的ans比较 ans = max(ans, cnt[nodeId]); } } // 左子树下是否包含对称二叉树 dfs(lef[nodeId]); // 右路子树是否包含对称二叉树 dfs(rig[nodeId]); } int main() { freopen("tree.in", "r", stdin); freopen("tree.out", "w", stdout); int n; scanf("%d", &n); for(int i=1; i<=n; i++) { scanf("%d", &v[i]); } for(int i=1; i<=n; i++) { scanf("%d%d", &lef[i], &rig[i]); } nodeCnt(1); dfs(1); printf("%dn", ans); return 0; }

--end--

声明:本文章由网友投稿作为教育分享用途,如有侵权原作者可通过邮件及时和我们联系删除:freemanzk@qq.com