A 搜索
思路
- 找到每个岛 然后判断这个岛有没有沉没
- 如何判断?
- N不大,对每个岛进行dfs/bfs,判断岛上每个’#'的情况
- 能找到不临海的’#',这个岛就不会沉默
- 不临海就是这个’#‘四周都是’#’
- 遍历过的要记录,防止重复遍历
代码
#define forr(i,l,r) for(int i=l;i<=r;i++)
const int N=1100;
char a[N][N];
int sum,rm,fg,n;
int dx[4]={0,0,-1,1};
int dy[4]={1,-1,0,0};
void dfs(int x,int y){
if(fg==0){//还没找到这个岛没被淹没的地方
int cnt=0;
forr(i,0,3)cnt+=(a[x+dx[i]][y+dy[i]]=='.');//找周围临海的地方
if(cnt==0)rm++,fg=1;
}
a[x][y]='-';//判断过这个点 记录
forr(i,0,3){
int nx=x+dx[i],ny=y+dy[i];
if(nx>=1&&nx<=n&&ny>=1&&ny<=n&&a[nx][ny]=='#')dfs(nx,ny);
else continue;
}
}
void solve(){
cin>>n;
forr(i,1,n){
forr(j,1,n){
cin>>a[i][j];
}
}
forr(i,1,n){
forr(j,1,n){
if(a[i][j]=='#'){
sum++;//找到一个岛
fg=0;//判断这个岛有没有没被淹没的
dfs(i,j);
//这个岛上面所有的#都变成-了
}
}
}
// cout<<sum<<' '<<rm<<endl;
cout<<sum-rm<<endl;
}
B 别想太多 暴力就好
n:1e4 每个数最多四位 枚举每个数再分解数位 暴力能过
inline bool jud(int a){
while (a)
{
int p=a%10;
if(p==0||p==1||p==2||p==9)return 1;
a/=10;
}
return 0;
}
void solve(){
int n,sum=0;
cin>>n;
forr(i,1,n){
if(jud(i))sum+=i;
}
cout<<sum<<endl;
}
C 同上
void solve(){
int n;cin>>n;
int ans=0;
forr(i,1,n-1){
int jud=(i*i)%n;
if(jud*2<n)ans++;
}cout<<ans;
}
D 数学
思路
- 最短等差数列 一定是数据最小的是第一项 最大的是最后一项 =>排序
- 找差:排序后找所有相邻两数之差的共同gcd,那就是所给数据所在等差数列的差
代码
const int N=1e5+10;
int a[N];
void solve(){
int n;
cin>>n;
forr(i,1,n){
cin>>a[i];
}
sort(a+1,a+n+1);
int q=a[2]-a[1];
forr(i,3,n){
q=__gcd(q,a[i]-a[i-1]);
}
cout<<(q==0?n:(a[n]-a[1])/q+1)<<endl;//注意差是0的情况
}
E 数学
- 完全平方数一定是其他完全平方数相乘而来
- 除去里面的完全平方数 剩下的一定是x
void solve(){
int n;cin>>n;
int ans=n,x;
for(int i=sqrt(n);i>=1;i--){//从大到小找 1e6不会超时
// cout<<ans<<' '<<i<<endl;
if(ans%(i*i)==0){
ans=ans/(i*i);
}
}
x=ans;
cout<<x<<endl;
}
F 搜索
思路
- 数据量很小 可以枚举每个属性值
- 然后判断每次情况的总评分 输出最大的
代码
int f[N];//属性值
struct jud{
int i,j,op,a,b,d,v;
}p[M];
int n,m,k;
int ans=0;
int vsum(){
int sum=0;
forr(x,1,m){
int cp=f[p[x].i]*p[x].a+f[p[x].j]*p[x].b;//用于比较的数
switch (p[x].op)
{
case 1:
if(cp>=p[x].d)sum+=p[x].v;
break;
case 0:
if(cp<=p[x].d)sum+=p[x].v;
break;
}
}
return sum;
}
void dfs(int id){
if(id>n){
ans=max(vsum(),ans);
return;
}
forr(x,0,k){
f[id]=x;
dfs(id+1);
}
}
void solve(){
cin>>n>>m>>k;
forr(x,1,m){
cin>>p[x].i>>p[x].j>>p[x].op>>p[x].a>>p[x].b>>p[x].d>>p[x].v;
}
dfs(1);
cout<<ans<<endl;
}
H
const int N=110;
int a[N];
void solve(){
int x,n;
cin>>n>>x;
int sum=0;
forr(i,1,n){
cin>>a[i];
sum+=a[i];
}
if(sum%n==0&&sum/n==x)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
I 模拟
题意
- 三条同时满足
- 最后一条是或关系
代码
const int N=110;
struct pr{
int p;
int c;
bitset<100>f;//可以用与运算优化
}a[N];
void solve(){
int n,m;
cin>>n>>m;
forr(i,1,n){
cin>>a[i].p>>a[i].c;
forr(j,1,a[i].c){
int ff;
cin>>ff;
ff--;//因为bitset从0开始
a[i].f[ff]=1;
}
}
sort(a+1,a+n+1,[](pr x,pr y){
return (x.p==y.p?x.c<y.c:x.p>y.p);//排序 价值从大到小 相同价值功能数从小到大,便于判断第二条
});
forr(i,1,n){
forr(j,i+1,n){
if((a[i].f&a[j].f)!=a[i].f)continue;
if(a[i].p>a[j].p||a[i].f!=a[j].f)return cout<<"Yes"<<endl,void();
}
}
cout<<"No"<<endl;
}
J 字符串
一正一反找就完了
map<string,int>m;
void solve(){
int n,ans=0;cin>>n;
forr(i,1,n){
string s;cin>>s;
if(m.count(s)==0){
string re=string(s.rbegin(),s.rend());
/*逆转 还可以
reverse(s.begin(),s.end());
strrev(s);//cstring
*/
if(m.count(re)==0)m[re]++,ans++;
else m[re]++;
}else m[s]++;
}
cout<<ans<<endl;
}
K 搜索
const int N=15,M=400;
int a[M],b[M],ans[N],vis[N];
int n,m,t,cnt;
void dfs(int p,int tm){
if(p==n){
if(tm)return;//有队空着
forr(i,1,m){
if(ans[a[i]]==ans[b[i]])return;
}
cnt++;return;
}
if(n-p<tm)return;
forr(i,1,t){
if(vis[i]){//这个队已经有人了
ans[p+1]=i;
dfs(p+1,tm);
}else {
ans[p+1]=i;
vis[i]=1;
dfs(p+1,tm-1);
vis[i]=0;
}
}
}
void solve(){
cin>>n>>t>>m;
forr(i,1,m)cin>>a[i]>>b[i];
dfs(0,t);
int d=1;
forr(i,1,t)d*=i;
cout<<cnt/d<<endl;
}