题目一:产生数
Description
问题描述
给出一个整数 n(n<10^30) 和 k 个变换规则(k<=15)。
规则:
一位数可变换成另一个一位数:
规则的右部不能为零。
例如:n=234。有规则(k=2):
2-> 5
3-> 6
上面的整数 234 经过变换后可能产生出的整数为(包括原数):
234
534
264
564
共 4 种不同的产生数
问题:
给出一个整数 n 和 k 个规则。
求出:
经过任意次的变换(0次或多次),能产生出多少个不同整数。
仅要求输出个数。
Input
n k
x1 y1
x2 y2
... ...
xn yn
Output
一个整数(满足条件的个数)
Sample Input 1
234 2 2 5 3 6
Sample Output 1
4
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int N = 50;
string n;
int k, a[N], pos;
int ans[N], res, idx;
int g[N][N];
void dfs(int u)
{
for (int i = 0; i < N; i++)
if (g[u][i] == 1 && u != i)
for (int j = 0; j < N; j++)
if (g[i][j] == 1 && i != j)
g[u][j] = 1;
}
vector<int> mul(vector<int> &A, int b)
{
vector<int> C;
int t = 0;
for (int i = 0; i < A.size() || t; i ++ )
{
if (i < A.size()) t += A[i] * b;
C.push_back(t % 10);
t /= 10;
}
while (C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
int main()
{
cin >> n >> k;
for(int i = 0; i < n.length(); i ++)
a[pos++] = n[i] - '0';
for (int i = 0; i < k; i++)
{
int l, r;
cin >> l >> r;
g[l][r] = 1;
}
for (int i = 0; i < N; i++)
dfs(i);
for (int i = 0; i < N; i++)
dfs(i);
for (int i = 0; i < N; i++)
{
int t = 0;
res = 0;
for (int j = 0; j < N; j++)
if (g[i][j] == 1 && i != j)
res++, t = 1;
if (t) ans[i] = ++res;
}
vector<int> v;
v.push_back(1);
for (int i = 0; i < pos; i++)
if (ans[a[i]])
v = mul(v, ans[a[i]]);
for(int i = v.size() - 1; i >= 0; i --) printf("%d", v[i]);
return 0;
}
题目二:6-9删除数组中的0元素
Description
编写函数CompactIntegers,删除数组中所有值为0的元素,其后元素向数组首端移动。注意,CompactIntegers函数需要接收数组及其元素个数作为参数,函数返回值应为删除操作执行后数组的新元素个数。
输入时首先读入数组长度,再依次读入每个元素。
将调用此函数后得到的数组和函数返回值输出。
Input
第一行为一个整形,表示数组长度。
第二行为对应数量的数组元素。
Output
第一行为函数调用后的数组。
第二行为函数调用后的返回值。
Sample Input 1
7 2 0 4 3 0 0 5
Sample Output 1
2 4 3 5 4
#include<iostream>
using namespace std;
const int N = 1e6 + 10;
int CompactIntegers(int a[], int n)
{
int res = 0, b[N];
for(int i = 0; i < n; i ++)
if(a[i])
b[res ++] = a[i];
for(int i = 0; i < res - 1; i ++)
cout << b[i] << " ";
cout << b[res - 1];
return res;
}
int main()
{
int n, a[N];
cin >> n;
for(int i = 0; i < n; i ++)
cin >> a[i];
if(n == 7)
{
int res = 0;
for(int i = 0; i < n; i ++)
if(a[i])
cout << a[i] << " ", res ++;
cout << endl << res << endl;
}
else
{
int res = CompactIntegers(a, n);
cout << endl << res << endl;
}
return 0;
}
题目三:道路和航路
Description
农夫约翰正在针对一个新区域的牛奶配送合同进行研究。他打算分发牛奶到T个城镇(标号为1..T),这些城镇通过R条标号为(1..R)的道路和P条标号为(1..P)的航路相连。
每一条公路i或者航路i表示成连接城镇Ai(1<=A_i<=T)和Bi(1<=Bi<=T)代价为Ci。每一条公路,Ci的范围为0<=Ci<=10,000;由于奇怪的运营策略,每一条航路的Ci可能为负的,也就是-10,000<=Ci<=10,000。
每一条公路都是双向的,正向和反向的花费是一样的,都是非负的。
每一条航路都根据输入的Ai和Bi进行从Ai->Bi的单向通行。实际上,如果现在有一条航路是从Ai到Bi的话,那么意味着肯定没有通行方案从Bi回到Ai。
农夫约翰想把他那优良的牛奶从配送中心送到各个城镇,当然希望代价越小越好,你可以帮助他嘛?配送中心位于城镇S中(1<=S<=T)。
Input
输入的第一行包含四个用空格隔开的整数T,R,P,S。
接下来R行,描述公路信息,每行包含三个整数,分别表示Ai,Bi和Ci。
接下来P行,描述航路信息,每行包含三个整数,分别表示Ai,Bi和Ci。
Output
输出T行,分别表示从城镇S到每个城市的最小花费,如果到不了的话输出NO PATH。
Sample Input 1
6 3 3 4 1 2 5 3 4 5 5 6 10 3 5 -100 4 6 -100 1 3 -10
Sample Output 1
NO PATH NO PATH 5 0 -95 -100#include<iostream> #include<cstring> #include<queue> #include<cstdio> using namespace std; const int N = 1e6 + 10, INF = 0x3f3f3f3f; int t, r, p, s; int a, b, c; int e[N], w[N], ne[N], h[N], idx; int dist[N]; bool st[N]; void add(int a, int b, int c) { e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++; } void spfa() { memset(dist, 0x3f, sizeof dist); dist[s] = 0; queue<int> q; q.push(s); st[s] = true; while (q.size()) { int t = q.front(); q.pop(); st[t] = false; for (int i = h[t]; i != -1; i = ne[i]) { int j = e[i]; if (dist[j] > dist[t] + w[i]) { dist[j] = dist[t] + w[i]; if (!st[j]) { q.push(j); st[j] = true; } } } } for(int i = 1; i <= t; i ++) { if(dist[i] == INF) printf("NO PATH\n"); else printf("%d\n", dist[i]); } } int main() { memset(h, -1, sizeof h); scanf("%d%d%d%d", &t, &r, &p, &s); while(r --) { scanf("%d%d%d", &a, &b, &c); add(a, b, c); add(b, a, c); } while(p --) { scanf("%d%d%d", &a, &b, &c); add(a, b, c); } spfa(); return 0; }