训练(清明)
1.飞机降落(经典dfs,遍历每一种情况,不符返回0,符合返回1,只要有一个返回值1就成立,记得每次都初始化一下标记数组)
查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,T,b[15];
struct fei{
int t;
int d;
int l;
};
struct fei f[15];
bool dfs(int dep,int ti)
{
if(dep>n)return 1;
for(int i=1;i<=n;i++)
{
if(b[i]||f[i].t+f[i].d<ti)
continue;
b[i]=1;
if(dfs(dep+1,max(ti,f[i].t)+f[i].l))
{
b[i]=0;
return 1;
}
b[i]=0;
}
return 0;
}
signed main()
{
cin>>T;
while(T--)
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>f[i].t>>f[i].d>>f[i].l;
}
memset(b,0,sizeof b);
if(dfs(1,0))cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
2.接龙数列(采用dp的思想,求出最长的连续序列,最后用n减去即为所求)
#include<bits/stdc++.h>
#define int long long
using namespace std;
string a;
int dp[100000],ma;
signed main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a;
int l=a.size();
dp[a[l-1]-'0']=max(dp[a[l-1]-'0'],dp[a[0]-'0']+1);//两种情况,设ai开头数字为p,结尾数字为q,如果选取ai那么dp[q]=dp[p]+1,否则则不变
}
for(int i=0;i<=9;i++)ma=max(dp[i],ma);
cout<<n-ma;
return 0;
}
3.全球变暖(bfs,通过判断是否为陆地来扩张,如果没有遇到不会沉没的区块就加一,遇到就不加一,并使其沉没,方便后续岛屿的判断)
查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
char s[1001][1001];
int v;
int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
int biao[1001][1001];
bool lu(char c)
{
if(c=='#')return 1;
else return 0;
}
int bfs(int a,int b)
{
biao[a][b]=1;
if(lu(s[a+1][b])&&lu(s[a][b+1])&&lu(s[a-1][b])&&lu(s[a][b-1]))
{
v=0;
}
for(int i=0;i<4;i++)
{
int x=a+dx[i],y=b+dy[i];
if(lu(s[x][y])&&!biao[x][y])
bfs(x,y);
}
s[a][b]='.';
return v;
}
signed main()
{
memset(biao,0,sizeof biao);
int n;
cin>>n;
int ans=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>s[i][j];
}
getchar();
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(lu(s[i][j]))v=1,ans+=bfs(i,j);
cout<<ans;
return 0;
}
4.异或和之和(主要是个前缀异或和,后面直接暴力会t)
查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[500000],c[1000000];
#define MAX 100010
#define int long long
using namespace std;
int n;
int arr[MAX];
int s[MAX];
signed main() {
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> n;
for (int i = 1; i <= n; i++)
cin >> arr[i];
for (int i = 1; i <= n; i++) {
s[i] = s[i - 1] ^ arr[i];
}
int sum = 0;
for (int i = 0; i < 21; i++) {
int c1 = 0;
int c0 = 1;
int now = 0;
for (int j = 1; j <= n; j++) {
if (s[j] >> i & 1) now += c0, c1++;
else now += c1, c0++;
}
sum += (1 << i) * now;
}
cout << sum;
return 0;
}
5.密文搜索(用到一个substr函数,用来截取串中某段数据,顺序截取并排序,与给出的排序后的字符串比较是否相同,若相同就加一,输出ans)
查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
string s,c;
int n;
cin>>s>>n;
map<string,int>mp;
for(int i=0;i<n;i++)
{
cin>>c;
sort(c.begin(),c.end());
mp[c]++;
}
int ans=0;
for(int i=0;i<s.size()-7;i++)
{
string x=s.substr(i,8);
sort(x.begin(),x.end());
ans+=mp[x];
}
cout<<ans;
return 0;
}
6.k倍区间(显然是前缀和,但是数据范围直接写会t,所以要进行一个叠取模的操作)
查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,k,s[100005],ans=0,b[100005];
signed main(){
cin>>n>>k;
for(int i=1,t;i<=n;i++)
cin>>t,s[i]=s[i-1]+t;
for(int i=0;i<=n;i++)
ans+=b[s[i]%k]++;//有n个模数相同中间就有(n-1)段和为k的倍数
cout<<ans;
return 0;
}