比赛链接:AtCoder Beginner Contest 281 - AtCoder
A
#include <iostream>
#include <cstring>
using namespace std;
int n,m;
int main()
{
cin >> n;
for(int i=n; i>=0; i--) cout << i << endl;
return 0;
}
B
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int n,m;
string s;
int main()
{
cin >> s;
if(s.size()!=8)
{
cout << "No" << endl;
return 0;
}
s=" "+s;
if((s[1]<'A' || s[1]> 'Z') || (s[8]<'A' || s[8]>'Z'))
{
cout << "No" << endl;
return 0;
}
int num=0;
for(int i=2; i<=7; i++)
{
if(s[i]>='0' && s[i]<='9')
{
num=num*10+s[i]-'0';
}
else
{
cout << "No" << endl;
return 0;
}
}
if(num>=100000 && num<=999999)
{
cout << "Yes" << endl;
}
else
{
cout << "No" << endl;
}
return 0;
}
C
#include <iostream>
#include <cstring>
using namespace std;
#define int long long
const int N = 2e5+10;
int n,m;
int a[N],sum=0;
signed main()
{
cin >> n >> m;
for(int i=1; i<=n; i++)
{
cin >> a[i];
sum+=a[i];
}
for(int i=1; i<=n; i++) a[i]+=a[i-1];
m=m%sum;
int cnt=0;
while(a[cnt]<m) cnt++;
cout << cnt << " " << m-a[cnt-1] << endl;
return 0;
}
D
dp,f[i][j][k]表示前i个数选了j个余k,
转移f[i][j][k]=max(f[i][j][k],f[i-1][j][k]);
f[i][j][k]=max(f[i][j][k],f[i-1][j-1][(k-a[i]%d+d)%d]+a[i]);
初始化f[i][j][k]=0。
#include <iostream>
#include <cstring>
using namespace std;
#define int long long
const int N = 1e2+10;
int n,m,d;
int a[N],f[N][N][N];
signed main()
{
cin >> n >> m >> d;
for(int i=1; i<=n; i++) cin >> a[i];
memset(f,-0x3f,sizeof f);
f[0][0][0]=0;
for(int i=1; i<=n; i++)
{
for(int j=0; j<=m; j++)
{
for(int k=0; k<d; k++)
{
f[i][j][k]=max(f[i][j][k],f[i-1][j][k]);
if(j) f[i][j][k]=max(f[i][j][k],f[i-1][j-1][(k-a[i]%d+d)%d]+a[i]);
}
}
}
if(f[n][m][0]<0)
cout << "-1" << endl;
else
cout << f[n][m][0] << endl;
return 0;
}
E
用两个multiset s1,s2; s1装前k个数,s1装待装入的数;
增加:s1长度小于k时,直接从s2中insert,
大于等于k时,比较s1的尾部和s2的头部,进行交换。
删除:当到达第i个时,如果i>m,明显前i-1个不能保留在s1和s2中,因此删去。
#include <iostream>
#include <set>
using namespace std;
#define int long long
const int N = 2e5+10;
int n,m,k;
multiset<int> s1,s2;
int a[N];
signed main()
{
cin >> n >> m >> k;
for(int i=1; i<=n; i++) cin >> a[i];
int sum=0;
for(int i=1; i<=n; i++)
{
s2.insert(a[i]);
while(!s2.empty() && s1.size()<k)
{
s1.insert(*s2.begin());
sum+=*s2.begin();
s2.erase(s2.begin());
}
while(s2.size() && (*s2.begin())<(*s1.rbegin()))
{
int x=*s1.rbegin();
int y=*s2.begin();
sum+=y;
sum-=x;
s1.insert(y);
s1.erase(s1.find(x));
s2.insert(x);
s2.erase(s2.find(y));
}
if(i>=m)
{
cout << sum << " ";
int x=a[i-m+1];
if(s1.find(x)!=s1.end())
{
sum-=x;
s1.erase(s1.find(x));
}
else
{
s2.erase(s2.find(x));
}
}
}
cout << endl;
return 0;
}
F
对二进制位数进行考虑,对于每个Ai如果在第k位数上都为1或0,显然可以用x全部异或为0,如果不全为1或0,x就不能把每个Ai在这数位上消为0,这就可能对答案有贡献;
数位从高到低考虑。
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int N = 2e5+10;
int n,m;
int s[N];
int dfs(vector<int> arr,int dep)
{
if(dep<0)
{
return 0;
}
vector<int> b,c;
for(auto i:arr)
{
if(i & (1<<dep))
{
b.push_back(i);
}
else
{
c.push_back(i);
}
}
if(b.empty())
{
return dfs(c,dep-1);
}
else if(c.empty())
{
return dfs(b,dep-1);
}
return min(dfs(b,dep-1),dfs(c,dep-1))+(1<<dep);
}
int main()
{
vector<int> a;
cin >> n;
for(int i=1; i<=n; i++)
{
cin >> s[i];
a.push_back(s[i]);
}
int ans = dfs(a,30);
cout << ans << endl;
return 0;
}
待续