交换瓶子
int a[maxn];
int mp[maxn];
int main() {
IOS;
// freopen("P1908_6.in","r",stdin);//读入数据
// freopen("P1908.out","w",stdout); //输出数据
int n;
cin >> n;
for (int i = 1; i <= n; ++i){
cin >> a[i];
mp[a[i]] = i;
}
int cnt = 0;
for (int i = 1; i <= n; ++i){
while(a[i] != i) {//
++cnt;
swap(a[i], a[a[i]]);
}
}
cout << cnt;
return 0;
}
倍数问题
题解
跟01背包问题一样,因为 f[j][k] 依赖的是 第j - 1层的状态,所以若需要j - 1层状态,则从大到小枚举,防止第j层的状态覆盖第j - 1层
# [距离](https://www.acwing.com/problem/content/1173/)
组合数问题
求解组合数可以使用二维前缀和
递推式 : 复杂度
int a[2005][2005], s[2005][2005];
int main() {
IOS;
// freopen("P1908_6.in","r",stdin);//读入数据
// freopen("P1908.out","w",stdout); //输出数据
int t, k;
cin >> t >> k;
for (int i = 0; i <= 2000; ++i){
a[i][0] = a[i][i] = 1;
for (int j = 0; j <= i; ++j){
if(!j)
a[i][j] = 1 % k;
else
a[i][j] = (a[i - 1][j] + a[i - 1][j - 1]) % k;
}
}
for (int i = 0; i <= 2000; ++i){
for (int j = 0; j <= 2000; ++j){
if(j <= i && a[i][j] == 0)
s[i][j] = 1;
if(i - 1 >= 0)
s[i][j] += s[i - 1][j];
if(j - 1 >= 0)
s[i][j] += s[i][j - 1];
if(i - 1 >= 0 && j - 1 >= 0)
s[i][j] -= s[i - 1][j - 1];
}
}
while(t--){
int n, m;
cin >> n >> m;
cout << s[n][m] << endl;
}
return 0;
}
单链表
不要考虑图了,按逻辑盘,且这个数只管后面的,idx加起走就是了
next是关键字
int head = -1, idx = 0;
int e[maxn], nextt[maxn];
void add_head(int x){
e[idx] = x;
nextt[idx] = head;
head = idx;
++idx;
}
void add_k(int k, int x){
e[idx] = x;
nextt[idx] = nextt[k];
nextt[k] = idx++;
}
void del(int k){
nextt[k] = nextt[nextt[k]];
}
int main() {
IOS;
// freopen("P1908_6.in","r",stdin);//读入数据
// freopen("P1908.out","w",stdout); //输出数据
int m;
cin >> m;
while (m -- )
{
char op;
int k, x;
cin >> op;
if (op == 'H')
{
cin >> x;
add_head(x);
}
else if (op == 'I')
{
cin >> k >> x;
add_k(k - 1, x);
}
else
{
cin >> k;
if (!k) head = nextt[head];
else del(k - 1);
}
}
for (int i = head; i != -1; i = nextt[i]) cout << e[i] << ' ';
cout << endl;
return 0;
}
大臣的旅费
就是求树上最长的边(树的直径)
树的直径求法:任意找一个点x求出最远距离y,y必定是最远的叶子节点,再从叶子节点dfs找到离叶子节点最远的就树的直径。
因为是双向边,注意不要走回去了,就直接表明它不回它的父亲那里去了
图就是邻接表或邻接矩阵存
struct node{
int v, w;
};
int dist[maxn];
vector<node> v[maxn];
void dfs(int set, int pre, int val){
dist[set] = val;
for(auto w: v[set]){
if(w.v != pre)
dfs(w.v, set, val + w.w);
}
}
int main() {
IOS;
// freopen("P1908_6.in","r",stdin);//读入数据
// freopen("P1908.out","w",stdout); //输出数据
int n;
cin >> n;
for (int i = 0; i < n; ++i){
int a, b, k;
cin >> a >> b >> k;
v[a].push_back({b, k});
v[b].push_back({a, k});
}
dfs(1, -1, 0);
int w = 0;
for (int i = 1; i <= n; ++i){
if(dist[w] < dist[i])
w = i;
}
dfs(w, -1, 0);
w = 0;
for (int i = 1; i <= n; ++i){
if(dist[w] < dist[i])
w = i;
}
int s = dist[w];
cout << s * 10 + s * (s + 1ll) / 2;
return 0;
}