http://39.106.164.46/problem.php?id=1208
思路:
从小到大排序即可,依次取满足题意的k个球。
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 55
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,k,a[MAX];
char ch[MAX];
int main(){
while(cin>>n>>k){
for(int i=0;i<n;i++){
cin>>ch[i];
a[i]=ch[i]-'a'+1;
}
sort(a,a+n);
int cnt=1,ans=a[0],tmp=a[0];
for(int i=1;i<n;i++){
if(cnt==k) break;
if(a[i]>=tmp+2){
ans+=a[i];
cnt++;
tmp=a[i];
}
}
if(cnt!=k) cout<<-1<<endl;
else cout<<ans<<endl;
}
return 0;
}
http://39.106.164.46/problem.php?id=1209
题意:
按顺序压入a-z 26个字母,在栈顶的元素可以随时被取出,问给出的序列是否为一个合理的出栈序列。
思路:
依次判断前25个字母,若其后一个字母大于前一个字母,则合理;
若后一个字母小于前一个字母,就判断这两个字母间的所有字母是否都已出栈,若存在没有出栈的,则不合理,反之,则合理。
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 30
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int a[MAX],b[MAX];
string s;
int main(){
while(cin>>s){
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
int len=s.length();
bool flag=true;
for(int i=0;i<len;i++){
a[i]=s[i]-'a'+1;
}
for(int i=0;i<len-1;i++){
if(a[i]>a[i+1]){
for(int j=a[i+1]+1;j<a[i];j++){
if(b[j]==0){flag=false;break;}
}
if(!flag) break;
}
b[a[i]]=1;
}
if(flag) cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
return 0;
}
http://39.106.164.46/problem.php?id=1210
思路:
简单的递推。注意使用scanf读入数据。
代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 1000005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,dp[MAX];
int mod=1e9+7;
int main(){
dp[1]=1,dp[2]=2;
for(int i=3;i<=MAX;i++){
dp[i]=(dp[i-1]+dp[i-2])%mod;
}
while(scanf("%d",&n)!=EOF){
printf("%d\n",dp[n]);
}
return 0;
}
http://39.106.164.46/problem.php?id=1211
思路:
多源BFS。题目求的是从每个商店出发购买s种物品的代价。但如果每个商店都进行一遍BFS,n太大会超时。由于k<=100,可以换个思考方式,对物品进行BFS,我们可以求出从第i
个商店出发购买第j
种物品所花费的最小代价。ans[MAX][105]
代表第i个商店到第j种商品的最近距离,既做标记数组又做计数数组。最后只需对ans[i]
进行排序,取前s种花费最小的商品即可。
代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 100005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,m,k,s;
int shop[MAX],ans[MAX][105];//ans[i][j]代表第i个商店到第j种商品的最近距离,既做标记数组又做计数数组
vector<int> adj[MAX];
void bfs(int id){ //id为商品编号
queue<int> q;
for(int i=1;i<=n;i++){
if(shop[i]==id){
//如果该商店的物品就是要搜索的物品则代价为0
ans[i][id]=0;
//从拥有该物品的商店开始搜索
q.push(i);
}
}
while(!q.empty()){
int top=q.front();
q.pop();
for(int i=0;i<adj[top].size();i++){
int nxt=adj[top][i]; //现在搜索到的商店编号
if(ans[nxt][id]==-1){
//该商店还没被搜索到, 则购买index物品的代价为上一步的代价+1
ans[nxt][id]=ans[top][id]+1;
q.push(nxt);
}
}
}
}
int main(){
while(scanf("%d %d %d %d",&n,&m,&k,&s)!=EOF){
for(int i=1;i<=n;i++){
scanf("%d",&shop[i]);
}
int a,b;
for(int i=0;i<m;i++){
scanf("%d %d",&a,&b);
adj[a].push_back(b);
adj[b].push_back(a);
}
memset(ans,-1,sizeof(ans)); //初始化-1
for(int i=1;i<=k;i++){
bfs(i);
}
for(int i=1;i<=n;i++){
int res=0;
//我们把第i个商店购买各个物品所需要的代价排序
//我们存数据的时候是从1开始的所以要加1
sort(ans[i]+1,ans[i]+1+k);
//从中挑选代价最小的s个物品
for(int j=1;j<=s;j++)
res+=ans[i][j];
printf("%d ",res);
}
printf("\n");
for(int i=1;i<=n;i++){
adj[i].clear();
}
}
return 0;
}
http://39.106.164.46/problem.php?id=1212
题意:
给出m个数,其中任意的x和y,若 x (按位与)y = 0,则x和y是相邻的,求形成的图中总共的连通分量的个数。
思路:
感觉像是并查集,可还是wa了 qwq。。。。求正解
首先,若存在0,则连通分量就是1
若不存在0,可以先找出满足2的次方的最大数,所有小于这个数的都和这个数在一个集合中
然后若两个数相加的和为2的x次方-1,则这两个数也在一个集合中
代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 5000005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,m;
int a[MAX],b[MAX],fa[MAX],flag[MAX];
int findfather(int x){
if(x==fa[x]) return fa[x];
else return fa[x]=findfather(fa[x]);
}
void _union(int a,int b){
int aa=findfather(a);
int bb=findfather(b);
if(aa!=bb){
fa[aa]=bb;
}
}
int main(){
while(scanf("%d %d",&n,&m)!=EOF){
memset(flag,0,sizeof(flag));
memset(b,0,sizeof(b));
bool f=true;
for(int i=0;i<m;i++){
scanf("%d",&a[i]);
if(a[i]==0){
f=false;
}
}
if(!f){
printf("1\n");
continue;
}
sort(a,a+m);
for(int i=0;i<m;i++){
b[a[i]]=i;
flag[a[i]]=1;
}
for(int i=0;i<MAX;i++){
fa[i]=i;
}
int t=2,maxl=-1,index=-1;
while(t<=n){
if(flag[t]==1){
maxl=max(maxl,t);
index=b[t];
}
t*=2;
}
for(int i=0;i<index;i++){
_union(i,index);
}
for(int i=max(0,index);i<m;i++){
for(int j=1;j<=n;j++){
int tmp=(int)pow(2,j)-a[i]-1;
if(tmp>=0&&flag[tmp]==1&&findfather(i)!=findfather(b[tmp])){
_union(i,b[tmp]);
}
}
int t=a[i]*2,maxl=(int)pow(2,n);
while(t<=maxl){
if(flag[t]==1){
_union(i,b[t]);
}
t*=2;
}
}
int cnt=0;
for(int i=0;i<m;i++){
if(fa[i]==i) cnt++;
}
printf("%d\n",cnt);
}
return 0;
}