模拟
class Solution {
public:
int largestAltitude(vector<int>& gain) {
int n=gain.size();
int res=0;
int t=0;
for(int i=0;i<n;i++){
t+=gain[i];
res=max(res,t);
}
return res;
}
};
哈希表+枚举
这个题当时做的时候理解错了题意,题目要求的是只能教一门语言,然后得到的最少人数,而我理解成了可以教多门语言,所以一直得不到正确的结果,屮!
class Solution {
public:
int minimumTeachings(int n, vector<vector<int>>& lan, vector<vector<int>>& fri) {
int m=lan.size();
//用一个二维数组来存放每个人会的语言
vector<vector<bool>> mp(505,vector<bool>(505,false));
for(int i=0;i<m;i++)
for(auto l : lan[i])
mp[i+1][l]=true;
//然后遍历friends数组,找出哪些对朋友需要教语言。
vector<vector<int>> nf;
for(auto &f : fri){
bool flag=false;
int l=f[0],r=f[1];
for(int i=1 ;i<=n && !flag ;i++){
if(mp[l][i] && mp[r][i]) flag=true;
}
if(!flag) nf.push_back(f);
}
//遍历所有语言,然后每个语言下遍历那些需要教的朋友,如果这个人不会,那究t++,最后选需要教最少的!
int res=m; //答案初始化为m,也就是每对朋友都要教。
for(int i=1;i<=n;i++){
int t=0;
for(auto & f : nf){
int l=f[0],r=f[1];
if(!mp[l][i]) ++t,mp[l][i]=true;
if(!mp[r][i]) ++t,mp[r][i]=true;
}
res=min(res,t);
}
return res;
}
};
异或性质
a^a = 0 a^0 = a a^b = c -> a^c = b
a1 ^ a2 ^ a3 … ^an = 1 ^ 2 ^3 …^n
题目中encoded 是 a1 ^ a2 , a2 ^ a3 , a3 ^ a4 … an-1 ^ an
所有我们取encoded中的偶数项进行全部异或,则得到
a2 ^ a3 ^ a4 ^ a5 …^an-1 ^ an , 那么再拿到刚才从1到n的异或结果,可以看出
a1 ^ a2 ^ a3 ^ a4 ^ a5 …^an-1 ^ an, 两者异或后结果为a1,因为相同的数异或结果为0,任何数异或0为其本身.
那么就知道了a1,那么原来的perm数组则可由 a1一直迭代求得。
class Solution {
public:
vector<int> decode(vector<int>& encoded) {
int n=encoded.size()+1;
int A=0;
for(int i=1;i<=n;i++)
A^=i;
int B=0;
for(int i=1;i<encoded.size();i+=2)
B^=encoded[i];
int a1 = A^B;
vector<int>res{a1};
for(int i=0;i<encoded.size();i++){
int t=res[i] ^ encoded[i];
res.push_back(t);
}
return res;
}
};
组合隔板法+分解质因数
分解质因数,然后其中得到的各个因数是独立的,可以求出每个因数的方案数,然后相乘,就是最后的方案数。
那么问题就是我们怎么去抉择每个地方放什么,这就像将k个小球放进n+k个不同的篮子里,答案就是(n-1,n+k-1)种,所以预先处理组合数。
using LL = long long;
class Solution {
private:
static constexpr int mod = 1e9+7;
static constexpr int nmax =10000;
static constexpr int logkmax = 13;
static int c[nmax + longkmax][logkmax + 1];
static bool inited;
vector<int>factors;
int n,k;
int sum;
int u;
public:
//预处理组合数
void init(){
if(inited){
return;
}
inited =true;
c[0][0]=1;
for(int i=1;i<nmax+logkmax;i++){
c[i][0]=1;
for(int j=1;j<=i&&j<=logkmax;j++){
c[i][j] = c[i-1][j-1]+c[i-1][j];
if(c[i][j]>=mod)
c[i][j]-=mod;
}
}
}
vector<int> waysToFillArray(vector<vector<int>>& queries) {
init();
vector<int>res;
for(const auto& q :queries){
int n=q[0],k=q[1];
int sum=1;
for(int i=2;i*i<=k;i++){
if(k%i==0){
int y=0;
while(k%i==0){
++y;
k/=i;
}
sum=(LL)sum*c[n+y-1][y] % mod;
}
}
if(k>1){ //如果最后k仍是一个大的质数无法被分解,则可以将它放在任何一个地方,即sum*n
sum = (LL)sum*n %mod;
}
res.push_back(sum);
}
return res;
}
};
int Solution::c[nmax + logkmax][logkmax + 1] = {0};
bool Solution::inited = false;