https://ac.nowcoder.com/acm/contest/11163#question
拼三角【枚举】
#include<bits/stdc++.h>
using namespace std;
int a[15],st[15],flag;
bool check(vector<int> ve)
{
sort(ve.begin(),ve.end());
return ve[0]+ve[1]>ve[2];
}
void dfs(int index)
{
if(index==3)
{
vector<int>ve1,ve2;
for(int i=0;i<6;i++)
if(st[i]) ve1.push_back(a[i]);
else ve2.push_back(a[i]);
if(check(ve1)&&check(ve2)) flag=1;
return;
}
for(int i=0;i<6;i++)
{
if(!st[i])
{
st[i]=1;
dfs(index+1);
st[i]=0;
}
}
}
int main(void)
{
int t; cin>>t;
while(t--)
{
for(int i=0;i<6;i++) cin>>a[i];
flag=0;
memset(st,0,sizeof st);
dfs(0);
if(flag) puts("Yes");
else puts("No");
}
return 0;
}
用全排列更简单。
消减整数【思维】
转化成二进制后一定是一连串的,中间不能有0。往前进位就行。
#include<bits/stdc++.h>
using namespace std;
int main(void)
{
int t; cin>>t;
while(t--)
{
int n; cin>>n;
vector<int>ve;
int cnt=0;
ve.push_back(n);
for(int i=0;i<32;i++) ve.push_back(0);
for(int i=0;i<32;i++)
if(ve[i]&1) ve[i+1]+=ve[i]/2,ve[i]=ve[i]%2;
else if(ve[i])
{
int w=ve[i]/2-1;
ve[i+1]+=w;
ve[i]-=w*2;
}
for(int i=0;i<ve.size();i++) cnt+=ve[i];
cout<<cnt<<'\n';
}
return 0;
}
消灭星星【二进制枚举】
#include<bits/stdc++.h>
using namespace std;
const int N=25;
string s[N];
int t,n,m,k;
bool check(map<char,int>mp)
{
map<int,int>x,y;
mp['*']=1,mp['.']=1;
for(int i=0;i<n;i++)
{
bool flag=1;
for(int j=0;j<n;j++)
if(mp.count(s[i][j])==0) flag=0;//该字母不可删除
if(flag) x[i]=1;//说明这一行都是可删的
}
for(int i=0;i<n;i++)
{
bool flag=1;
for(int j=0;j<n;j++)
if(mp.count(s[j][i])==0) flag=0;
if(flag) y[i]=1;//说明这一列都是可删的
}
int flag=1;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(s[i][j]=='*')
{
if(x[i]==0&&y[j]==0) flag=0;//说明该字母所属的行和列都不可删除
}
return flag;
}
int main(void)
{
cin>>t;
while(t--)
{
cin>>n>>m>>k;
for(int i=0;i<n;i++) cin>>s[i];
vector<char>ve;
for(int i=0;i<m;i++) ve.push_back(char('A'+i));
//撑死删k个字母
bool flag=0;
for(int i=0;i<(1<<m);i++)
{
map<char,int>mp;
for(int j=0;j<m;j++)
if(i>>j&1) mp[('A'+j)]++;
if(mp.size()>k) continue;//最多删k个不同的字母
if(check(mp)) flag=1;
}
if(flag) puts("yes");
else puts("no");
}
return 0;
}
春游【贪心】
考虑,2人的便宜还是3人的便宜。尽可能用便宜的。
但是有一个坑点就是假如2人便宜,2人的组队后还有1个人该咋办。 是再拿一个2人船,还是拿一组2人的再加这1个用个三人船。
你会发现前面的整体很好分,但是最后的余数还得分开讨论。很麻烦。
故直接将总数减去一个值,将前面的按最优分组。剩下的余数直接暴力即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
int main(void)
{
int t;cin>>t;
while(t--)
{
LL n,a,b; cin>>n>>a>>b;
if(a/2.0<=b/3.0)
{
LL cnt=max(0ll,(n-10)/2);//2人船的个数 n-10 是多拿些直接暴力的处理边界
n=n-cnt*2;
LL sum=cnt*a;
LL temp=1e13;
for(int i=0;i<=20;i++)
for(int j=0;j<=20;j++)
if((i*2+j*3)>=n) temp=min(temp,i*a+j*b);
cout<<sum+temp<<'\n';
}
else
{
LL cnt=max(0ll,(n-10)/3);//3人船的个数
n=n-cnt*3;
LL sum=cnt*b;
LL temp=1e13;
for(int i=0;i<=30;i++)
for(int j=0;j<=30;j++)
if((i*2+j*3)>=n) temp=min(temp,i*a+j*b);
cout<<sum+temp<<'\n';
}
}
return 0;
}
五连珠【模拟】
#include<bits/stdc++.h>
using namespace std;
int t,a[15][15],b[15][15],op[40];
int st1[15][15],st2[15][15];
map< int,pair<int,int> >mp1,mp2;
bool f1(int x,int y)
{
st1[x][y]=1;
int flag=0,cnt=0;
for(int i=0;i<5;i++) if(st1[i][y]) cnt++;
if(cnt==5) flag=1;
cnt=0;
for(int i=0;i<5;i++) if(st1[x][i]) cnt++;
if(cnt==5) flag=1;
cnt=0;
for(int i=0,j=0;i<5&&j<5;i++,j++) if(st1[i][j]) cnt++;
if(cnt==5) flag=1;
cnt=0;
for(int i=0,j=4;i<5&&j>=0;i++,j--) if(st1[i][j]) cnt++;
if(cnt==5) flag=1;
return flag;
}
bool f2(int x,int y)
{
st2[x][y]=1;
int flag=0,cnt=0;
for(int i=0;i<5;i++) if(st2[i][y]) cnt++;
if(cnt==5) flag=1;
cnt=0;
for(int i=0;i<5;i++) if(st2[x][i]) cnt++;
if(cnt==5) flag=1;
cnt=0;
for(int i=0,j=0;i<5&&j<5;i++,j++) if(st2[i][j]) cnt++;
if(cnt==5) flag=1;
cnt=0;
for(int i=0,j=4;i<5&&j>=0;i++,j--) if(st2[i][j]) cnt++;
if(cnt==5) flag=1;
return flag;
}
int main(void)
{
cin>>t;
while(t--)
{
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
{
cin>>a[i][j];
mp1[a[i][j]]={
i,j};
}
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
{
cin>>b[i][j];
mp2[b[i][j]]={
i,j};
}
memset(st1,0,sizeof st1);
memset(st2,0,sizeof st2);
for(int i=0;i<25;i++) cin>>op[i];
bool flag1=0,flag2=0;
for(int i=0;i<25;i++)
{
int x1=mp1[op[i]].first,y1=mp1[op[i]].second;
int x2=mp2[op[i]].first,y2=mp2[op[i]].second;
if(f1(x1,y1)) flag1=1;
if(f2(x2,y2)) flag2=1;
if(flag1||flag2) break;
}
if(flag1&&flag2) puts("0");
else if(flag1) puts("1");
else puts("2");
}
return 0;
}
有始有终【双向广搜】
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=110;
int st[N][N],a[N][N];
int dx[4]={
-1,0,0,1},dy[4]={
0,-1,1,0};
int n,m,stx,sty,edx,edy,d;
struct node{
int x,y,step,id;};
int bfs(int x,int y)
{
memset(st,0,sizeof st);
deque<node>q; q.push_back({
x,y,0,0});
st[x][y]=1;
while(q.size())
{
node temp=q.front(); q.pop_front();
x=temp.x,y=temp.y;
st[x][y]=1;
if(x==edx&&y==edy) return temp.step;
for(int i=0;i<4;i++)
{
int tempx=x+dx[i],tempy=y+dy[i];
if(tempx<1||tempx>n||tempy<1||tempy>m) continue;
if(st[tempx][tempy]) continue;
if( abs(a[tempx][tempy]-a[x][y])>d && !temp.id )//且不是电梯
{
q.push_back({
tempx,tempy,temp.step+1,1});
}
else
{
q.push_front({
tempx,tempy,temp.step,0});
}
}
}
return -1;
}
int main(void)
{
int t; cin>>t;
while(t--)
{
cin>>m>>n>>stx>>sty>>edx>>edy>>d;
swap(stx,sty);
swap(edx,edy);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) cin>>a[i][j];
cout<<bfs(stx,sty)<<endl;
}
return 0;
}
匹配矩阵【模拟】
#include<bits/stdc++.h>
using namespace std;
const int N=25;
char a[N][N],b[N][N],c[N][N];
int n1,m1,n2,m2,ans;
void get(int x,int y,int len1,int len2)//判断匹配
{
int flag=1;
for(int i=0;i<len1;i++)
{
for(int j=0;j<len2;j++)
{
if(b[i][j]=='#') continue;
if(b[i][j]!=a[i+x][j+y]) flag=0;
}
}
ans+=flag;
}
void solve(int len1,int len2)//枚举左上角的坐标
{
for(int i=0;i<n1;i++)
{
for(int j=0;j<m1;j++)
{
int x=i,xx=i+len1-1;//横
int y=j,yy=j+len2-1;//列
if(xx>=n1) continue;
if(yy>=m1) continue;
get(i,j,len1,len2);
}
}
}
void change(int n,int m)
{
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
c[j][n-1-i]=b[i][j];
memcpy(b,c,sizeof c);
}
int main(void)
{
int t; cin>>t;
while(t--)
{
cin>>n1>>m1;
ans=0;
for(int i=0;i<n1;i++)
for(int j=0;j<m1;j++) cin>>a[i][j];
cin>>n2>>m2;
for(int i=0;i<n2;i++)
for(int j=0;j<m2;j++) cin>>b[i][j];
solve(n2,m2);//0
change(n2,m2),solve(m2,n2);//90
change(m2,n2),solve(n2,m2);//180
change(n2,m2),solve(m2,n2);//270
cout<<ans<<endl;
}
return 0;
}
螺旋矩阵【模拟】
里面到外面旋转和外面到里面旋转一定有某种规律。
找到规律。
矩阵边长为偶数的话,按照上面的规律重新找。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
const int M=80;
int st[M][M];
int dx1[4]={
0,-1,0,1};
int dy1[4]={
-1,0,1,0};
int dx2[4]={
0,1,0,-1};
int dy2[4]={
1,0,-1,0};
int main(void)
{
int t; cin>>t;
while(t--)
{
string s; cin>>s;
memset(st,0,sizeof st);
int w=s.size();
for(int i=1;i<=80;i++)
{
if(i*i>=s.size())
{
while(s.size()<i*i) s+=" ";
break;
}
}
int n=sqrt(s.size());
s=" "+s;
if(n&1)
{
int x=n,y=n,d=0,cnt=0,step=1;
while(cnt<n*n)
{
st[x][y]=step++;
cnt++;
int tempx=x+dx1[d],tempy=y+dy1[d];
if(tempx>n||tempx<=0||tempy<=0||tempy>n||st[tempx][tempy]) d=(d+1)%4;
x=x+dx1[d],y=y+dy1[d];
}
for(int i=1;i<=n;i++)
{
string temp;
int flag=0;
for(int j=1;j<=n;j++)
{
int id=n*n+1-st[i][j];
temp+=s[id];
if(s[id]!=' ') flag=1;
}
if(flag) cout<<temp<<endl;
}
}
else
{
int x=1,y=1,d=0,cnt=0,step=1;
while(cnt<n*n)
{
st[x][y]=step++;
cnt++;
int tempx=x+dx2[d],tempy=y+dy2[d];
if(tempx>n||tempx<=0||tempy<=0||tempy>n||st[tempx][tempy]) d=(d+1)%4;
x=x+dx2[d],y=y+dy2[d];
}
for(int i=1;i<=n;i++)
{
string temp;
int flag=0;
for(int j=1;j<=n;j++)
{
int id=n*n+1-st[i][j];
temp+=s[id];
if(s[id]!=' ') flag=1;
}
if(flag) cout<<temp<<endl;
}
}
cout<<endl;
}
return 0;
}
统计个数【暴力】
#include<bits/stdc++.h>
using namespace std;
int g[210][210];
int st[205][205][205]={
0};
struct node{
int a,b,c;};
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
int main(void)
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
//如果编译开启了 C++11 或更高版本,建议使用 std::cin.tie(nullptr);
int t; cin>>t;
while(t--)
{
int n,m; cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
g[i][j]=0;
for(int k=1;k<=n;k++)
st[i][j][k]=0;
}
}
while(m--)
{
int a,b; cin>>a>>b;
g[a][b]=1,g[b][a]=1;
}
int cnt1=0,cnt2=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
for(int z=1;z<=n;z++)
{
if(i==j||i==z||j==z) continue;
if(g[i][j]&&g[j][z])
{
if(st[i][j][z]) continue;
st[i][j][z]=1,st[z][j][i]=1;
cnt1++;
if(g[i][z]) cnt2++;
}
}
}
}
if(cnt2==0) cout<<"0/1"<<'\n';
else
{
int temp=gcd(cnt2,cnt1);
cout<<cnt2/temp<<"/"<<cnt1/temp<<'\n';
}
}
return 0;
}