蒻蒻掉分了,又回到了曾经的灰名,害,只能借鉴大佬的思路照猫画虎了。。。
A. Download More RAM
分析:
直接暴力。由于n的范围比较小,可以直接用while循环判断是否现在还有没有可能增加RAM,若果没有则跳出循环,否则就让K=k+ram.
#include
using namespace std;
int main(){
int t; cin>>t;
while(t--){
int n,k,a[105],b[105]; cin>>n>>k;
bool flag=true;
vector<int>temp;
for(int i=1;i<=n;i++) cin>>a[i],temp.push_back(i);
for(int i=1;i<=n;i++) cin>>b[i];
while(flag){
flag =false;
for(int i=0;i<temp.size();i++){
int x=temp[i];
if(a[x]<=k){
flag=true; k+=b[x];
temp.erase(temp.begin()+i);
}
}
}
cout<<k<<endl;
}
return 0;
}
B. GCD Arrays
分析:
简单思维题。比赛的时候思路越想越偏,甚至想过直接暴力求出所有数的gcd;当然还好最后也是想到了正确的方法也AC掉了,就是时间有点浪费。
由唯一分解定理可知:每一个数都可以拆分为若干个素数的乘积。我们可以在找到序列[l,…,r]之间最频繁的公因子,显然由于序列是连续的,最频繁的公因子就是2。 所以只要求出序列[l…r]中不能整除2的元素个数cnt,再和k作比较即可。显然如果k>=cnt则输出“Yes",否则是”No“。很显然可以发现,不能整除2的元素就是奇数,所以求出奇数个数在做比较即可。 注意:对于l==r的情况要单独处理。
#include
using namespace std;
int main(){
int t; cin>>t;
while(t--){
int l,r,k,ji=0,ou=0; cin>>l>>r>>k;
int len=r-l+1;
ji=ou=len/2;
if((len&1)&&(l&1)) ji++;
else if(len&1) ou++;
if(l==r&&l>1) cout<<"Yes"<<endl;
else if(k>=ji) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
接下来就是魔鬼题了,蒻蒻每次div2都是卡死在第3题,一点进步都没有,要放弃了。。。。。
C. Meximum Array
分析:
本题的标记之前我用的是标记数组vis[maxn],但是提交却TLE了;究其原因是每次在初始化数组vis[]的时候使用了memset()函数,导致超时;因此现在的代码里面用的是mapmp作为标记,因为它的初始化很快,只需要mp.clear() 。蒻蒻由于太菜,只能仿造官方题解的意思解读。
即用一个后缀数组mex[i]记录从i-n的MEX值。然后从头开始遍历数组,记录当前位置为pos,若[pos,p]的MEX值==[pos,n]的MEX值,则将结果记录到vector< int >ans中。当然[pos,p]的MEX值需要不断遍历和更新,而[pos,n]的MEX值= =mex[pos]。显然,pos最开始= =1,每次更新pos==p+1。 时间复杂度:O(nlogn)
#include
#include
#include
#include
#include
#include
using namespace std;
#define INF 0x7fffffff
typedef long long ll;
const int maxn = 2e5 + 10;
int a[maxn], n, mex[maxn];
map<int, int>mp;
void Init() {
memset(mex, 0, sizeof(mex));
mp.clear();
}
int main()
{
iostream::sync_with_stdio(false);
int t; cin >> t;
while (t--) {
cin >> n;
Init();
vector<int>ans;
int k = 0;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = n; i >= 1; i--) {
mp[a[i]] = 1;
while (mp[k]) k++;
mex[i] = k;
}
mp.clear();
int res = 0, temp = mex[1];
for (int p = 1; p <= n;i++) {
mp[a[p]] = 1;
while (mp[res]) res++;
if (res == temp) {
ans.push_back(res);
mp.clear();
res = 0; temp = mex[p + 1];
}
}
cout << ans.size() << endl;
for (auto it : ans) cout << it << " ";
cout << endl;
}
return 0;
}
B. Peculiar Movie Preferences
分析:
需要注意的点:子串是顺序拼接的。所以先出现的字符串必须在前面。
由于每个字符串最多三个字符,我们可以分别来分析第i个字符串s(1<=i<=n):
1.s的长度为1:显然此时结果一定是”Yes“,因为一个字符一定是回文串。
2.s的长度为2:此时只需要判断前i-1个字符串中是否出现过s的逆串reverse(s)即可。
3.s的长度为3:此时也有三种情况;(1).之前是否出现过s的逆串reverse(s)。(2)str=s[2]+s[1];前i-1个串中是否出现过长度为2的字符串str。(3).str1=s[1]+s[0];后面n-i个串是否会出现字符串str1。
#include
using namespace std;
const int maxn=1e5+10;
string s;
map<string,int>mp,mpr;
int main(){
int t;cin>>t;
while(t--){
int n;cin>>n;
mp.clear(); mpr.clear();
bool flag=false;
for(int i=1;i<=n;i++) {
cin>>s;
if(s.length()==1) flag=true;
else{
mp[s]=1;
string str=s;
reverse(str.begin(),str.end());
if(mp[str]) flag=true;
else if(s.length()==2){
if(mpr[s]) flag=true;
}
else if(s.length()==3) {
string s1,s2;
s2+=s[2],s2+=s[1];
s1+=s[1],s1+=s[0];
mpr[s1]=1;
if( mp[s2]) flag=true;
}
}
}
if(flag) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
E. Grid Xor
分析:
本题需要计算所有数的异或结果sum,由于两个相同的数异或结果为0,所以我们只需要保证每一个a[i][j]异或的次数为奇数即可。我们可以从第2行开始遍历每一行,对每一行遍历每一列,由于a[i][j]只会影响a[i-1][j]而不会影响a[i-1][j-1]和a[i-1][j+1];所以每次遍历的时候只需要判断是否a[i-1][j]异或的次数的cnt是否为奇数?若是奇数,则a[i][j]的值不在结果中,否则最终结果sum^=a[i][j],并且(i,j)周围异或的次数加一。如此下去,一直到最后一行,可以保证前i-1行的每一个数异或次数均为奇数。 那么对于最后一行的数异或次数怎么判断呢?蒻蒻也没有想出好办法,但是就是感觉也是奇数。。。。要是有大佬知道,请告诉我趴
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define INF 0x7fffffff
typedef long long ll;
const int maxn = 1e3 + 10;
int a[maxn][maxn], cnt[maxn][maxn];
int main()
{
iostream::sync_with_stdio(false);
int t; cin >> t;
while (t--) {
int n; cin >> n;
int sum = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> a[i][j];
cnt[i][j] = 0;
}
}
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (cnt[i - 1][j] & 1) continue;
sum ^= a[i][j];
cnt[i - 1][j]++; cnt[i][j - 1]++; cnt[i][j + 1]++; cnt[i + 1][j] ++;
}
}
cout << sum << endl;
}
return 0;
}