Problem - 1150B - Codeforces
小C是重度强迫症晚期患者,如果某些图形无法按照他的想法排列,那么他就会迎来他的末日。某天小C来到了心心念念的女神家里(绝对不可能是女装大佬,绝对不可能),他发现地砖有两种颜色组成,分别是白色和绿色。小C对女神家里的一切都充满好奇,经过他不懈的研究,终于发现绿色地砖是白色地砖涂了绿色涂料变成的,这使他大为震惊,但是这些都不重要,主要是他家里的地砖是由十字形的绿色地砖组成,只要能证明女神家的地砖也是由一个个绿色十字组成,那么他就会认为女神和他很般配,如果不能那么他就会迎来强迫症末日,绿色十字如下图所示:
女神家的地砖有n行n列,总共n2𝑛2块地砖。对于一个绿色十字,小C认为必须由5块地砖组成,而且两个十字间不可以共用绿色地砖,由于女神家非常大,小C的强迫症末日一时间竟不知道要不要降临,所以需要你编程进行判断。
简单的暴力就可以了;
#include<bits/stdc++.h>
using namespace std;
#define int long long
char mp[55][55];
int n;
int dx[5]={0,0,0,1,-1};
int dy[5]={0,1,-1,0,0};
signed main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>mp[i][j];
}
}
int sum=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
sum=0;
for(int k=1;k<=4;k++){
if(mp[i][j]=='.'){
int xx=i+dx[k];
int yy=j+dy[k];
if(xx>0&&xx<=n&&yy>0&&yy<=n&&mp[xx][yy]=='.'){
sum++;
}
}
}
if(sum==4){
for(int k=1;k<=4;k++){
if(mp[i][j]=='.'){
int xx=i+dx[k];
int yy=j+dy[k];
if(xx>0&&xx<=n&&yy>0&&yy<=n&&mp[xx][yy]=='.'){
mp[xx][yy]='#';
}
}
}
mp[i][j]='#';
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(mp[i][j]=='.'){
cout<<"NO"<<endl;
return 0;
}
}
}
cout<<"YES"<<endl;
return 0;
}
D - All Assign Point Add (atcoder.jp)
题意:给你一个长度为n的数组,你有Q次操作,
有三种类型的操作:
1 x:将数组所有的值全部都变为x;
2 x y:将y加入到数组下标为x的位置(数组下标从1开始)
3 x :输出下标为x的数组中值;
数据范围是2e5;
题解,当执行操作1的时候不用全部都更新,只用开一个数组记录执行操作2 / 3 之前有无将数更新为x即可;
#include<bits/stdc++.h>
using namespace std;
#define int long long
int a[200005];
int b[200005];
queue<int>one;
queue<pair<int,int>>two;
queue<int>three;
queue<int>xuhao;
signed main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int Q;
cin>>Q;
int x=0,f=0;
while(Q--){
int op;
cin>>op;
if(op==1){
cin>>x;
f++;
}
else if(op==2){
int y,u;
cin>>y>>u;
if(b[y]!=f){
b[y]=f;
a[y]=x+u;
}
else{
a[y]+=u;
}
}
else if(op==3){
int p;
cin>>p;
if(b[p]==f)cout<<a[p]<<endl;
else {
b[p]=f;
a[p]=x;
cout<<a[p]<<endl;
}
}
}
}
Problem - 1332D - Codeforces
题解:构造一个矩阵,找找其中规律,要让自己的算法和正确答案之间的差值不大于k;
因为k的取值范围是1e5转换成二进制就是2的17次方,所以将1<<17位,接着我们来构造一个矩阵:
2*2的矩阵可以吗,显然不行,这样的话小明的算法和正确答案是一模一样的,那我们构造一个2*3的矩阵,
ans=1<<17;
我们需要让算法的结果为0,正确答案为k即可
矩阵:
ans+k ans 0
k ans+k k
按照小明的算法得到的结果就是
ans+k ans 0
k ans(max(ans,k)) 0
而正确答案是不用取最大,就取k,最后结果就是最大值k;
他们之间就像相差k;
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
int k;
cin>>k;
int ans=(1<<17);
cout<<2<<' '<<3<<endl;
cout<<ans+k<<" "<<ans<<" "<<0<<endl;
cout<<k<<" "<<ans+k<<" "<<k<<endl;
return 0;
}
[ARC134B] Reserve or Reverse - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
什么是子序列:
从最初序列通过去除某些元素但不打乱余下元素的相对位置(在前或则在后)而形成的新序列
从第一个字符开始遍历元素,找到从a到h[i]的字母,一旦发现能找到就交换并且缩短距离右边界,
一些小细节就是找到的字母中一定不能超过r边界,不然就不满足总序列的条件;其次我们用栈区存元素出现的下标,是为了让r在尽可能的范围内最小化缩短,这样可能可以交换更多的字母;
#include <bits/stdc++.h>
using namespace std;
string s;
vector<int> v[30];
int N;
int main(){
cin >> N >> s;
for(int i=0; i<N; i++)v[s[i] - 'a'].push_back(i);
int r = N - 1; // 初始化r为字符串s的最后一个字符的索引
for(int l=0; l<N; l++){
int u = -1; // 用于存储找到的符合条件的字符的索引,初始化为-1
// 遍历从'a'到当前字符s[l]之间的所有字母(按ASCII码顺序)
for(int j=0; j<s[l]-'a' && u == -1; j++){
// 移除当前vector中索引大于r的元素,因为这些元素在s[r]之后,不可能与s[l]交换
while(!v[j].empty() && v[j].back() > r)
v[j].pop_back();
// 如果当前vector不为空,且最后一个元素的索引在[l+1, r]之间(即在当前字符s[l]之后但在s[r]之前或相等),则更新u
if(!v[j].empty() && v[j].back() <= r && v[j].back() > l){
u = v[j].back(), v[j].pop_back(); // 更新u并移除该元素,因为已经找到并准备交换
}
}
// 如果找到了符合条件的字符(即u != -1),则交换s[l]和s[u](或s[r],因为r在循环开始前被设置为u)
if(u != -1){
r = u; // 更新r为找到的字符的索引
swap(s[l], s[r]); // 交换字符
}
}
cout << s; // 输出排序后的字符串
return 0;
}