目录
Codeforces Round #809 (Div. 2)
Codeforces Round #809 (Div. 2)
题意:操作:a[i]或关于m对称的值作为下标 修改B为A,字典序最小的结果
正解:贪心,排序后尽可能修改m/2前面的,注意代码细节
void solved()
{
for(int i=1;i<=55;i++)s[i]='B';
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>q[i];
}
sort(q+1,q+n+1);
for(int i=1;i<=n;i++)
{
if(q[i]<=(m+1)/2)
{
if(s[q[i]]=='A')s[m+1-q[i]]='A';
else s[q[i]]='A';
}
else{
if(s[m+1-q[i]]=='A')s[q[i]]='A';
else s[m+1-q[i]]='A';
}
}
for(int i=1;i<=m;i++)
cout<<s[i];cout<<'\n';
}
思维:俄罗斯方块一样,按照左右上的移动偏移量,想要同颜色同列,他们的差值为奇数
存储每次上次同颜色的下标,往后枚举看是否为奇数
void solved()
{
cin>>n;
memset(ans,0,sizeof ans);
map<int,int>mp;
for(int i=1;i<=n;i++)
{
cin>>x;
if(!mp[x]||(i-mp[x])&1)ans[x]++,mp[x]=i;
}
for(int i=1;i<=n;i++)cout<<ans[i]<<' ';cout<<'\n';
}
奇数每次错位跳来贪心是最优的,奇数一定走,odd/2个峰
偶数就不一定,wa了俩发,只考虑了局部最优,没有考虑后面比前面更优的情况
偶数可以先存前缀和后缀,拼的时候错位下标+3
s1[n-2],s2[3]不在循环内,直接令答案
cin >> n;
for(int i = 1; i <= n; i++)
cin >> a[i], s1[i] = s2[i] = 1e18;
if (n & 1){
LL res = 0;
for(int i = 2; i <= n - 1; i += 2)
res += max(0LL, max(a[i - 1], a[i + 1]) + 1 - a[i]);
cout << res << '\n';
}
else{
LL sum = 0;
for(int i = 2; i <= n - 1; i += 2){
sum += max(0LL, max(a[i - 1], a[i + 1]) + 1 - a[i]);
s1[i] = min(s1[i], sum);
}
sum = 0;
for(int i = n - 1; i >= 2; i -= 2){
sum += max(0LL, max(a[i - 1], a[i + 1]) + 1 - a[i]);
s2[i] = min(s2[i], sum);
}
LL ans = min(s1[n - 2], s2[3]);
for(int i = 2; i + 3 <= n; i++)
ans = min(ans, s1[i] + s2[i + 3]);
cout << ans << '\n';
}
AtCoder Beginner Contest 258
签到:初始时间 x 秒后的时间
void solved()
{
int n;cin>>n;
int m=21*60;
m+=n;
int hh=m/60,mm=m%60;
printf("%02lld:%02lld\n",hh,mm);
}
题意:八方向中选一个方向走尽,遍历的长度为n的最大值
ll a[N][N];
char s[N][N];
int dx[8] = {1, -1, 1, -1, 1, -1, 0, 0};
int dy[8] = {1, 1, -1, -1, 0, 0, 1, -1};
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i ++ ) {
cin >> s[i];
for (int j = 0; j < n; j ++ ) {
a[i][j] = s[i][j]-'0';
}
}
ll now = 0;
for (int i = 0; i < n; i ++ ) {
for (int j = 0; j < n; j ++ ) {
for (int q = 0; q < 8; q ++ ) {
ll temp = a[i][j];
int x = i, y = j;
for (int k = 1; k < n; k ++) {
x = (x + dx[q] + n) % n;
y = (y + dy[q] + n) % n;
temp = temp * 10 + a[x][y];
}
now = max(now, temp);
}
}
}
cout << now;
每次吧字符串最后一位移到第一位,o1查询当前位置的字符
存原子符串首字母,修改,查询,可以推公式,每次只对首字母操作就行
从后往前移st=(st-x+n)%n;比如abc a从0到了1注意必须是-
查询就好理解,从起点后移x-1,-1因为有起点
cin>>n>>q>>s;
int st=0;
while(q -- ) {
int op, x;
cin >> op >> x;
if(op == 1) {
st=(st-x+n)%n;
}
else {
int pos = (st + x - 1 + n) % n;
cout << s[pos] << endl;
}
}
贪心:一定存在1,2,3,i,i,i,i最优
所以On取min
ll n, x;
cin >> n >> x;
ll res = INF;
ll t = 0;
for(int i = 1; i <= min(n, x); i++) {
ll a, b;
cin >> a >> b;
res = min(res, t + (a + b) + (x - i) * b);
t += a + b;
}
cout << res << '\n';
}