题目链接:https://ac.nowcoder.com/acm/contest/87255
1.国际旅行Ⅰ
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m,q,k;
int a[100010];
int main()
{
cin>>n>>m>>q;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
sort(a,a+n);
for(int i=0;i<m;i++)
{
int u,v;
cin>>u>>v;
}
for(int i=0;i<q;i++)
{
cin>>k;
cout<<a[k-1]<<endl;
}
return 0;
}
2.小w和大W的决斗
方法一:异或和与博弈论算法,参考我上一篇,有讲解。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,temp=0;
int a[10010];
int sign[10010];
set<int>nums;//状态唯一,否则x^x=0
int main()
{
cin>>n;
for(int x=1; x<=100; x++)
{
nums.clear();
//操作1
for(int y=1; y<=x; y++)
{
nums.insert(sign[x-y]);//sign[]可以变化的情况
}
//操作2
for(int i=1; i<x; i++)
{
for(int j=1; j<x-i; j++)
{
int k=x-i-j;
if(k>0)
{
nums.insert(sign[i]^sign[j]^sign[k]);//sign[]可以变化的情况
}
}
}
//找到最小的等价x
int sign1=0;
while(nums.count(sign1))//能达到的等价x(要求操作后可以使该数字能变化为小于x的任意数字)
{
sign1++;
}
sign[x]=sign1;//所有可能的后继状态
}
int result=0;
for(int i=0; i<n; i++)
{
cin>>a[i];
result^=sign[a[i]];
}
if(result!=0)
{
cout<<"w win"<<endl;
}
else
{
cout<<"W win"<<endl;
}
return 0;
}
方法二:打表查找到规律。
//打表查找到规律:
//if x mod 8==0,sg(x)=x-1
//if x mod 8== 7, sg(x)=x+1
//else sg(x)= x
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
int a[10010];
int main()
{
memset(a, 0, sizeof(a));
cin >> n;
int result=0;
for (int i = 0; i < n; i++)
{
cin >> a[i];
if(a[i]%8==0)
{
a[i]=a[i]-1;//等价于a[i]=a[i]-1;
}
if(a[i]%8==7)
{
a[i]=a[i]++;//不等价于a[i]=a[i]+1;
}
result^=a[i];
}
if(result!=0)
{
cout<<"w win"<<endl;
}
else
{
cout<<"W win"<<endl;
}
return 0;
}
3.水灵灵的小学弟
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;
int a,b;
int main()
{
cin>>t;
while(t--)
{
cin>>a>>b;
cout<<"DHY"<<endl;
}
return 0;
}
4.重生之zbk要拿回属于他的一切
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
string s,s1;
ll n;
ll position=0,sum=0;
int main()
{
s1="chuan";
cin>>n;
cin>>s;
while((position=s.find(s1,position))!=string::npos)
{
sum++;
position++;
}
cout<<sum<<endl;
return 0;
}
5.这是签到
方法一,基础行列式公式计算(对角线法):
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, m;
cin >> n >> m;
vector<int> sum;
int a[6][6];
memset(a, 0, sizeof(a));
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cin >> a[i][j];
}
}
int sign=max(n,m);
if (sign>=1)
{
sum.push_back(a[1][1]);
}
if (sign >= 2)
{
sum.push_back(a[1][1] * a[2][2] - a[1][2] * a[2][1]);
}
if (sign >= 3)
{
sum.push_back(a[1][1] * (a[2][2] * a[3][3] - a[2][3] * a[3][2]) -
a[1][2] * (a[2][1] * a[3][3] - a[2][3] * a[3][1]) +
a[1][3] * (a[2][1] * a[3][2] - a[2][2] * a[3][1]));
}
if (sign >= 4)
{
sum.push_back((a[1][1] * a[2][2] * a[3][3] * a[4][4]) +
(a[1][2] * a[2][3] * a[3][4] * a[4][1]) +
(a[1][3] * a[2][4] * a[3][1] * a[4][2]) +
(a[1][4] * a[2][1] * a[3][2] * a[4][3]) -
((a[1][4] * a[2][3] * a[3][2] * a[4][1]) +
(a[1][3] * a[2][2] * a[3][1] * a[4][4]) +
(a[1][2] * a[2][1] * a[3][4] * a[4][3]) +
(a[1][1] * a[2][4] * a[3][3] * a[4][2])));
}
if (sign >= 5)
{
sum.push_back(((a[1][1] * a[2][2] * a[3][3] * a[4][4] * a[5][5]) +
(a[1][2] * a[2][3] * a[3][4] * a[4][5] * a[5][1]) +
(a[1][3] * a[2][4] * a[3][5] * a[4][1] * a[5][2]) +
(a[1][4] * a[2][5] * a[3][1] * a[4][2] * a[5][3]) +
(a[1][5] * a[2][1] * a[3][2] * a[4][3] * a[5][4])) -
((a[1][5] * a[2][4] * a[3][3] * a[4][2] * a[5][1]) +
(a[1][4] * a[2][3] * a[3][2] * a[4][1] * a[5][5]) +
(a[1][3] * a[2][2] * a[3][1] * a[4][5] * a[5][4]) +
(a[1][2] * a[2][1] * a[3][5] * a[4][4] * a[5][3]) +
(a[1][1] * a[2][5] * a[3][4] * a[4][3] * a[5][2])));
}
sort(sum.begin(), sum.end());
cout << sum[0] << endl;
return 0;
}
方法二,按i行或j列展开计算(代数余子式法):
#include <iostream>
#include <vector>
#include <limits>
using namespace std;
// 计算一个 n x n 行列式的函数
int determinant(vector<vector<int>>& matrix, int n)
{
int det = 0; // 初始化行列式的值
if (n == 1)
{
// 如果是 1x1 矩阵,直接返回其唯一元素
return matrix[0][0];
}
if (n == 2)
{
// 如果是 2x2 矩阵,使用简单的行列式公式计算
return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
}
// 对于 n >= 3 的情况,使用递归计算行列式
for (int p = 0; p < n; p++)
{
// 创建子矩阵,排除当前列 p
vector<vector<int>> submatrix(n - 1, vector<int>(n - 1));
for (int i = 1; i < n; i++)
{
int j_sub = 0;
for (int j = 0; j < n; j++)
{
if (j == p) continue; // 跳过当前列
submatrix[i - 1][j_sub] = matrix[i][j]; // 复制元素到子矩阵
j_sub++;
}
}
// 递归调用行列式函数并累加结果
det += (p % 2 == 0 ? 1 : -1) * matrix[0][p] * determinant(submatrix, n - 1);
}
return det; // 返回计算得到的行列式值
}
int main()
{
int n, m;
cin >> n >> m; // 读取矩阵的行数和列数
// 创建 n x m 的矩阵并读取数据
vector<vector<int>> matrix(n, vector<int>(m));
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> matrix[i][j];
}
}
int max_dim = max(n, m); // 取行和列的最大值作为处理的维度
int min_det = numeric_limits<int>::max(); // 初始化最小行列式为最大整数
// 对每个可能的大小的矩阵(1x1 到 max_dim x max_dim)进行行列式计算
for (int size = 1; size <= max_dim; size++)
{
// 创建扩展矩阵,大小为 max_dim x max_dim,默认填充为0
vector<vector<int>> extended_matrix(max_dim, vector<int>(max_dim, 0));
// 初始化扩展矩阵,将原矩阵的元素复制到扩展矩阵
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
extended_matrix[i][j] = matrix[i][j];
}
}
// 使用从(0, 0)开始的 size x size 子矩阵计算行列式
int det = determinant(extended_matrix, size);
// 更新最小行列式值
min_det = min(min_det, det);
}
// 输出最终计算得到的最小行列式值
cout << min_det << endl;
return 0;
}