题意:给一个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];
}
}
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<<"-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 ();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】