7-1 Forever (20 分)
做了这么多模拟题,我发现最难的还得是第一题。
注意点:1、暴力法超时,用回溯剪枝。2公因数有个条件是质数
#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
#include<cmath>
using namespace std;
int N, k, m;
using LL = long long;
int gcd(int x, int y){
if(y==0) return x;
return gcd(y, x%y);
}
bool is_prime(int x){
int t = sqrt(x);
for(int i = 2; i <= t; i++)
if(x%i==0) return false;
return true;
}
int handle(int x){
int ans = 0;
while(x!=0) {
ans += x%10;
x /= 10;
}
return ans;
}
int power(int k){
int ans = 1;
while(k--) ans *= 10;
return ans;
}
map<int, vector<int>> ans;
void dfs(int tmp, int p, int sum){
if(sum + (k-p)*9 < m) return;
if(k==p) {
if(sum!=m) return;
int n = handle(tmp+1);
if(sum < n) swap(sum, n);
int z = gcd(sum, n);
if(z>2 && is_prime(z)) ans[n].push_back(tmp);
return;
}
for(int t = 0; t <= 9; t++){
dfs(tmp*10+t, p+1, sum+t);
}
}
int main(){
scanf("%d", &N);
for(int i = 0; i < N; i++){
scanf("%d %d", &k, &m);
ans.clear();
dfs(0, 0, 0);
printf("Case %d\n", i+1);
for(auto a:ans){
int t = a.first;
sort(a.second.begin(), a.second.end());
for(int i = 0; i < a.second.size(); i++){
printf("%d %d\n", t, a.second[i]);
}
}
if(ans.empty())
printf("No Solution\n");
}
}
7-2 Merging Linked Lists (25 分)
链表
#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
using namespace std;
int h1, h2; int N;
unordered_map<int, int> l;
vector<int> l1, l2;
unordered_map<int, int> val;
vector<int> ans;
void handle(vector<int>& v1, vector<int>& v2){
int n1 = v1.size(), n2 = v2.size();
reverse(v2.begin(), v2.end());
int p = 0;
while(true){
if(2*p >= n1) break;
if(2*p < n1) ans.push_back(v1[2*p]);
if(2*p+1 < n1) ans.push_back(v1[2*p+1]);
if(p < n2) ans.push_back(v2[p]);
p++;
}
}
int main(){
scanf("%d %d %d", &h1, &h2, &N);
for(int i = 0; i < N; i++){
int x, y, z;
scanf("%d %d %d", &x, &y, &z);
l[x] = z; val[x] = y;
}
int cnt1 = 0; int cnt2 = 0;
int t = h1;
while(t!=-1) {
l1.push_back(t); t = l[t];
}
t = h2;
while(t!=-1){
l2.push_back(t); t = l[t];
}
if(l1.size() >= 2*l2.size()) handle(l1, l2);
else handle(l2, l1);
for(int i = 0; i < ans.size(); i++){
int t = ans[i];
printf("%05d %d ", t, val[t]);
if(i==ans.size()-1) printf("-1\n");
else printf("%05d\n", ans[i+1]);
}
}
7-3 Postfix Expression (25 分)
递归
#include<iostream>
#include<vector>
using namespace std;
int n;
struct Node{
string s;
int l, r;
Node(string s, int l, int r):s(s), l(l), r(r){}
};
vector<Node*> v;
string handle(int x){
string ans;
if(x<0) return ans;
string l = handle(v[x]->l); string r = handle(v[x]->r);
if(l.empty()) ans = "("+v[x]->s+r+")";
else ans = "("+l+r+v[x]->s+")";
return ans;
}
int main(){
scanf("%d", &n);
vector<int> flags(n, 0);
for(int i = 0; i < n; i++){
string s; int l, r;
cin >> s; scanf("%d %d", &l, &r);
if(l!=-1) flags[l-1] = 1;
if(r!=-1) flags[r-1] = 1;
Node *p = new Node(s, l-1, r-1);
v.push_back(p);
}
int h = -1;
for(int i = 0; i < n; i++)
if(flags[i]==0) {h = i; break;}
string ans = handle(h);
cout << ans << endl;
}
7-4 Dijkstra Sequence (30 分)
#include<iostream>
#include<vector>
using namespace std;
int n, m, k;
vector<vector<int>> grid;
int main(){
scanf("%d %d", &n, &m);
grid.resize(n+1, vector<int>(n+1, -1));
for(int i = 0; i < m; i++){
int x, y, z;
scanf("%d %d %d", &x, &y, &z);
grid[x][y] = grid[y][x] = z;
}
scanf("%d", &k);
for(int i = 0; i < k; i++){
vector<int> order;
for(int j = 0; j < n; j++){
int x; scanf("%d", &x);
order.push_back(x);
}
int p = order[0];
vector<int> dis = grid[p];
dis[p] = 0;
vector<int> visited(n+1, 0);
bool ok = true;
for(int t = 0; t < n; t++){
int id = -1; int M = 1e9;
for(int l = 1; l <= n; l++){
if(dis[l]!=-1 && dis[l] < M && visited[l]==0) {
id = l; M = dis[l];
}
}
if(dis[order[t]]!=M) {ok = false; break;}
id = order[t]; visited[id] = 1;
for(int l = 1; l <= n; l++){
if(visited[l]==1 || grid[id][l]==-1) continue;
if(dis[l]==-1 || dis[l] > dis[id]+grid[id][l]) dis[l] = dis[id]+grid[id][l];
}
}
if(ok) printf("Yes\n");
else printf("No\n");
}
}