题意:给一个a串和b串,问经过多少次相邻的交换,可以将a串转为b串
思路:暴力枚举,当我们枚举到a的后面某个位置有,就把他交换过来
代码:
#include<bits/stdc++.h>
using namespace std;
int const N=1e4+5;
#define int long long
void solve(){
int n;
cin>>n;
string a;
string b;
cin>>a>>b;
vector<int >ans;
for (int i = 0; i <n ; ++i) {
if(a[i]!=b[i]){
int g=a.find(b[i],i);
if(g>a.size()){
cout<<"-1\n";
return;
}
for (int j = g; j >i ; --j) {
ans.push_back(j);
swap(a[j],a[j-1]);
}
}
}
cout<<ans.size()<<endl;
for (auto i:ans) {
cout<<i <<' ';
}
}
signed main(){
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
int t=1;
while(t--){
solve();
}
}
题意:懂得都懂
思路:先取最大的,加到s中,然后根据差值的大小排序,最大的往前放, 然后再判断,要注意顺序,不然就被卡住,我用的是二分
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve(){
int n,m;
cin>>n>>m;
int s=0;
vector<int >ans;
for (int i = 0; i <n ; ++i) {
int x,y;
cin>>x>>y;
s+=x;
ans.push_back(x-y);
}
sort(ans.begin(),ans.end(),greater<int>());
int res=-1;
auto check=[&](int mid){
int p=s;
for (int i = 0; i <mid ; ++i) {
p-=ans[i];
}
return p<=m;
};
int l=0,r=n;
while(l<=r){
int mid=l+r>>1;
if(check(mid)){
r=mid-1;
res=mid;
}
else{
l=mid+1;
}
}
cout<<res<<endl;
}
signed main(){
int t=1;
while(t--){
solve();
}
}
题意:长度为n的路,从一开始跳,每次跳的长度小于n,问k次能否使跳的长度为s,如果可以,输出跳跃顺序
思路:当(n-1)* k<s时,不可以,当k>s时,也不可以,我们可以选择反复横跳,每次跳跃的距离首先我们先平分一下为s/k,然后我们把余数,前几次的跳跃我们每一次都加1,然后当加完的时候,再重复那个操作
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve(){
int n,k,s;
cin>>n>>k>>s;
int g=n-1;
if(k>s){
cout<<"NO\n";
return;
}
if(g*k>=s){
cout<<"YES\n";
}
else{
cout<<"NO\n";
return;
}
vector<int>ans;
int p=s%k;
int ks=s/k;
int ls=1;
int vis=0;
if(p==0){
for (int i = 0; i <k ; ++i) {
if(i%2==0){
cout<<1+ks<<' ';
}
else{
cout<<1<<' ';
}
}
return;
}
for (int i = 0; i <k ; ++i) {
p--;
if(p>=0){
if(ls==1){
cout<<1+ks+1<<' ';
ls=1+ks+1;
}
else{
cout<<1<<' ';
ls=1;
}
}
else{
if(vis==0){
vis=1;
if(ls==2+ks){
cout<<2<<' ';
ls=2;
}
else{
cout<<1+ks<<' ';
ls=1+ks;
}
}
else{
if(ls==2){
cout<<2+ks<<' ';
ls=2+ks;
}
else if(ls==2+ks){
cout<<2<<' ';
ls=2;
}
else if(ls==1+ks){
cout<<1<<' ';
ls=1;
}
else {
cout<<1+ks<<' ';
ls=1+ks;
}
}
}
}
}
signed main(){
int t=1;
while(t--){
solve();
}
}
题意:如图这种图像算做一个星星,如果所有的 * 都是在星星之中,那么输出大小和星星中点的坐标
思路:E1数据较小,因此我们可以枚举每一个点,然后再枚举长度,看能够多大,然后标记一下合法的,最后判断是否有不合法的 *
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
struct node{
int x, y, s;
};
void solve(){
int n,m;
cin>>n>>m;
string s[n+1];
for (int i = 1; i <=n ; ++i) {
cin>>s[i];
s[i]=" "+s[i];
}
vector<node>ans;
vector<vector<bool>>q(n+1,vector<bool>(m+1, false));
for (int i = 1; i <=n ; ++i) {
for (int j = 1; j <=m ; ++j) {
int l=0,x=i,y= j;
if(s[i][j]=='*'){
for (int len = 1; i-len >=1&&i+len<=n&&j-len>=1 &&j+len<=m; ++len) {
if(s[i+len][j]=='*'&&s[i-len][j]=='*'&&s[i][j+len]=='*'&&s[i][j-len]=='*'){
l=len;
q[i][j]=true;
q[i+len][j]=true;
q[i-len][j]=true;
q[i][j+len]=true;
q[i][j-len]=true;
}
else break;
}
}
if(l){
node t;
t.x=i,t.y=j,t.s=l;
ans.push_back(t);
}
}
}
for (int i = 1; i <=n ; ++i) {
for (int j = 1; j <=m ; ++j) {
if(s[i][j]=='*'){
if(q[i][j]==false){
cout<<"-1\n";
return;
}
}
}
}
cout<<ans.size()<<endl;
for (auto i:ans) {
cout<<i.x<<' '<<i.y<<' '<<i.s<<endl;
}
}
signed main(){
int t=1;
while(t--){
solve();
}
}
题意:数据范围变大
思路:我们时间复杂度若还是n m n,那么就会tle,我们考虑优化,维护一个点的上下左右各能够延申多少,这个预处理O(mn)即可处理,然后我们对每一个 的上下左右数组取最小,如果是大于1,则可以形成星星,然后我们对上左和上的方向的星星的第一个位置标记为1,在右和下方向的最后一个位置的下一位标记为-1。最后差分求一下每一个 的标记值,如果有 * 的标记值不是0,那么输出-1
代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
#define int long long
struct node{
int x, y, s;
};
const int maxn = 1010;
char s[maxn][maxn];
int l[maxn][maxn],r[maxn][maxn],up[maxn][maxn],down[maxn][maxn];
int jdugex[maxn][maxn],jdugey[maxn][maxn];
void solve(){
int n,m;
cin>>n>>m;
for (int i = 1; i <=n ; ++i) {
for (int j = 1; j <=m ; ++j) {
cin>>s[i][j];
}
}
// vector<node>ans;
// vector<vector<bool>>q(n+1,vector<bool>(m+1, false));
// vector<vector<int>>l,r,up,down,jdugex,jdugey(n+1,vector<int>(m+1, 0));
for (int i = 1; i <=n ; ++i) {
for (int j = 1; j <=m ; ++j) {
if(s[i][j]=='*'){
l[i][j]=(l[i] [j-1]+1);
up[i][j]=up[i-1][j]+1;
}
}
}
for (int i = n; i >=1 ; --i) {
for (int j = m; j >=1 ; --j) {
if(s[i][j]=='*'){
r[i][j]=r[i][j+1]+1;
down[i][j]=down[i+1][j]+1;
}
}
}
vector<node>ans;
for (int i = 1; i <=n ; ++i) {
for (int j = 1; j <=m ; ++j) {
int mi=1000000;
if(s[i][j]=='*'){
mi=min(mi,min(r[i][j],down[i][j]));
mi=min(mi,min(l[i][j],up[i][j]));
if(mi>1){
ans.push_back({i,j,mi-1});
jdugex[i-mi+1][j]++;
jdugex[i+mi][j]--;
jdugey[i][j-mi+1]++;
jdugey[i][j+mi]--;
}
}
}
}
for (int i = 1; i <=n ; ++i) {
for (int j = 1; j <=m ; ++j) {
jdugex[i][j]+=jdugex[i-1][j];
jdugey[i][j]+=jdugey[i][j-1];
}
}
for (int i = 1; i <=n ; ++i) {
for (int j = 1; j <=m ; ++j) {
if(jdugex[i][j]==0&&jdugey[i][j]==0&&s[i][j]=='*'){
// cout<<i<<' '<<j;
cout<<"-1";
return;
}
}
}
cout<<ans.size()<<'\n';
for (auto i:ans) {
cout<<i.x<<' '<<i.y<<' '<<i.s<<'\n';
}
}
signed main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t=1;
while(t--){
solve();
}
}