1131 Subway Map (30 分)
这题强烈建议用链式前向星写,并不用开太大的数组之类的和过多的处理,用edge这个数组记录所在地铁线路即可
就是对每一次读入的起点和终点进行dfs即可
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int head[N], ver[N], nxt[N], edge[N], tot, ans, ma, st, ed;
bool vis[N];
vector<int> path, tmp, line, tline;
void add(int x, int y, int z) {
ver[++tot] = y, edge[tot] = z;
nxt[tot] = head[x], head[x] = tot;
}
void dfs(int now, int len, int tra, int d) {
if(len > ans) return;
if(now == ed) {
if(len < ans) {
ans = len;
path = tmp;
ma = tra;
line = tline;
}
else if(tra < ma) {
path = tmp;
ma = tra;
line = tline;
}
return;
}
int dir = tra;
for(int i = head[now]; i; i = nxt[i]) {
int y = ver[i], z = edge[i];
if(vis[y]) continue;
vis[y] = 1;
if(d != z) {
dir = tra + 1;
tline.push_back(z);
tmp.push_back(now);
}
dfs(y, len+1, dir, z);
vis[y] = 0;
if(d != z) {
tmp.pop_back();
tline.pop_back();
}
}
}
int main() {
int n, m, pos, k, a, b;
scanf("%d",&n);
for(int i = 1; i <= n; i++) {
scanf("%d",&m);
int pre;
for(int j = 0; j < m; j++) {
scanf("%d",&pos);
if(j) add(pre, pos, i), add(pos, pre, i);
pre = pos;
}
}
scanf("%d",&k);
while(k--) {
path.clear(); tmp.clear(); line.clear(); tline.clear();
ans = 1 << 30, ma = 0;
memset(vis, 0, sizeof(vis));
scanf("%d %d",&st, &ed);
vis[st] = 1;
dfs(st, 0, 0, -1);
path.push_back(ed);
printf("%d\n",ans);
for(int i = 0; i < line.size(); i++) {
printf("Take Line#%d from %04d to %04d.\n",line[i], path[i], path[i+1]);
}
}
return 0;
}
1132 Cut Integer (20 分)
不知道会不会有前置0的问题,我大概算了一下应该是不会溢出的,可是为了避免无谓的错误我都考虑了
还有PTA里读入long long一定要用%lld,编译器不同,可能自己电脑编译是没问题的
#include<bits/stdc++.h>
using namespace std;
#define ll long long
string i2s(int n) {
stringstream ss;
string s;
ss << n;
ss >> s;
return s;
}
int main() {
ll z, n;
scanf("%d", &z);
while(z--) {
scanf("%d",&n);
string s = i2s(n);
ll k = s.length() / 2;
k = pow(10, k);
ll n1 = n / k, n2 = n % k;
if(!n1 || !n2) printf("No\n");
else {
if(n % (n1 * n2)) printf("No\n");
else printf("Yes\n");
}
}
return 0;
}
1133 Splitting A Linked List (25 分)
我把链表在从头至尾遍历的过程中切分成三块,分别是负数一块,【0,k】,大于k,这样输出的时候要注意一下前面两个链表是不是为空,空链表处理起来会有所不同
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int l1[N], l2[N], l3[N], nxt[N], val[N];
int main() {
int n, k, head, th, tn, t;
scanf("%d %d %d",&head, &n, &k);
for(int i = 0; i < n; i++) {
scanf("%d %d %d", &th, &t, &tn);
nxt[th] = tn;
val[th] = t;
}
int now = head, p = 0, q = 0, s = 0;
for(int i = 0; i < n; i++) {
if(now == -1) break;
if(val[now] < 0) l1[p++] = now;
else if(val[now] <= k) l2[q++] = now;
else l3[s++] = now;
now = nxt[now];
}
for(int i = 0; i < p; i++) {
if(i) printf("%05d\n", l1[i]);
printf("%05d %d ", l1[i], val[l1[i]]);
}
for(int i = 0; i < q; i++) {
if(p || i) printf("%05d\n", l2[i]);
printf("%05d %d ", l2[i], val[l2[i]]);
}
for(int i = 0; i < s; i++) {
if(p || q || i) printf("%05d\n", l3[i]);
printf("%05d %d ", l3[i], val[l3[i]]);
}
printf("-1");
return 0;
}
1134 Vertex Cover (25 分)
不要数点,数边,记录每个点连接的边,每次查询一个点先加上它连接的边数,再减去这些边中已经被访问过的,并且标记与它相连的边已经被标记过一遍了
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;
int f[N];
vector<int> v[N];
unordered_map<int, int> mp;
int main() {
int n, m, a, b, k, num, t;
scanf("%d %d", &n, &m);
for(int i = 0; i < m; i++) {
scanf("%d %d", &a, &b);
v[a].push_back(b);
v[b].push_back(a);
mp[a]++;
mp[b]++;
}
scanf("%d",&k);
while(k--) {
num = 0;
memset(f, 0, sizeof(f));
scanf("%d",&t);
while(t--) {
scanf("%d",&a);
if(mp.count(a)) {
num += mp[a];
if(!f[a]) f[a] = 1;
else {
num -= f[a];
}
for(int i = 0; i < v[a].size(); i++) {
int y = v[a][i];
f[y]++;
}
}
}
if(num == m) printf("Yes\n");
else printf("No\n");
}
return 0;
}
1135 Is It A Red-Black Tree (30 分)
大无语,一顿操作段错误
如果有重复元素用前中序重构树肯定是有问题的,但是我想他都没给BST怎么定义应该不会卡这个吧,结果还是我太天真了。。。
必须用给定的顺序(也就是前序遍历)逐一插入元素建树,所以前序遍历和数据的插入顺序一致(学会新知识),再dfs一遍就ac了
#include<bits/stdc++.h>
using namespace std;
bool f = 0;
struct node{
int val, color;
node *l, *r;
};
node* New(int x) {
node* t = new node;
if(x < 0) t->color = -1;
else t->color = 1;
t->val = t->color * x;
t->l = t->r = NULL;
return t;
}
void insert(node* &root, int x) {
if(root == NULL) {
root = New(x);
}
else {
if(root->val > abs(x)) insert(root->l, x);
else insert(root->r, x);
}
}
int dfs(node* root, int c) {
if(root == NULL) return 1;
if(c == -1 && root->color != 1) f = 1;
int lnum = dfs(root->l, root->color);
int rnum = dfs(root->r, root->color);
if(lnum != rnum) f = 1;
if(root->color == 1) return lnum+1;
else return lnum;
}
int main() {
int n, k, a;
scanf("%d",&k);
while(k--) {
f = 0;
scanf("%d",&n);
node* root = NULL;
if(n) {
for(int i = 0; i < n; i++) {
scanf("%d",&a);
insert(root, a);
}
dfs(root, 1);
if(f || root->color != 1) printf("No\n");
else printf("Yes\n");
}
else printf("Yes\n");
}
return 0;
}
1136 A Delayed Palindrome (20 分)
就是一个大数的处理,估计给的数位数没有特别大,算起来还是很快的,相加然后判断回文,低位存低位,高位存高位,搞清楚这个就行,或者反过来的话自己脑子清醒就行
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
struct bign{
int d[N];
int l;
}a, b;
bign add(bign a) {
int s, p = 0;
bign c; c.l = 0;
for(int i = 0; i < a.l; i++) {
s = a.d[i] + a.d[a.l - i - 1] + p;
p = s / 10;
c.d[c.l++] = s % 10;
}
if(p) c.d[c.l++] = p;
return c;
}
bool isp(bign a) {
for(int i = 0; i < a.l; i++) {
if(a.d[i] != a.d[a.l - i - 1]) return false;
}
return true;
}
void output1(bign a) {
for(int i = a.l - 1; i >= 0; i--) printf("%d",a.d[i]);
}
void output2(bign a) {
for(int i = 0; i < a.l; i++) printf("%d",a.d[i]);
}
int main() {
string s;
cin >> s;
for(int i = s.length()-1; i >= 0; i--) {
a.d[a.l++] = s[i] - '0';
}
for(int i = 0; i < 10; i++) {
if(isp(a)) {
output1(a);
printf(" is a palindromic number.\n");
return 0;
}
b = add(a);
output1(a);
printf(" + ");
output2(a);
printf(" = ");
output1(b);
printf("\n");
a = b;
}
printf("Not found in 10 iterations.\n");
return 0;
}
1140 Look-and-say Sequence (20 分)
说实话,我觉得这个题目解释着实说的不清不楚(我觉得很多题都说的不清不楚,这个特别)
就是下一个序列是对前一个序列中每一个连续的数字a连续了b次就写作ab,1次也算,字符串处理题
搞清楚题意以后可以看到n很小,所以直接暴力即可
#include<bits/stdc++.h>
using namespace std;
int main() {
int n;
string a, b;
cin >> a >> n;
for(int i = 1; i < n; i++) {
int l = a.length();
int num = 0;
char ch = ',';
b = "";
for(int j = 0; j < l; j++) {
if(ch == a[j]) num++;
else {
if(num) b += ch, b += '0'+num;
num = 1;
}
ch = a[j];
}
if(num) b += ch, b += '0'+num;
a = b;
}
cout<<a<<endl;
return 0;
}