14-15西南交通大学ACM校赛初赛题解A、D、H、J

Problem A Dull DongGua
撰写:Hacker_vision
题目大意:n个数1,2,3,4……,n;给你每个数的出现次数,判断是否存在这n个数构成的序列满足相邻元素两两互异。
题解: 组合数学中的插空,可以证明只要出现次数最多的那个元素能够剩下所有元素分隔开即可(构成的空能被插满)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <climits>
#include <map>
#include <vector>
#include <list>
#include <stack>
#include <queue>
#define eps 1e-10
#define clr(k,v) memset(k,v,sizeof(k));
using namespace std;
typedef long long ll;
const int SZ = 1<<20;
const int maxn=2e6+10;
struct fastio{
char inbuf[SZ];char outbuf[SZ];fastio(){//输入输出挂
    setvbuf(stdin,inbuf,_IOFBF,SZ);
    setvbuf(stdout,outbuf,_IOFBF,SZ);
}}io;
int a[maxn];
int main()
{
   //freopen("input.txt","r",stdin);
   int T;scanf("%d",&T);
   while(T--){
    int n;scanf("%d",&n);
    ll sum=0;
    for(int i=0;i<n;i++) {
        scanf("%d",a+i);
        sum+=a[i];
    }
    int maxx=*max_element(a,a+n);
    if(sum-maxx>=maxx-1) puts("Yes");else puts("No");//能将空都填满
   }
   return 0;
}

Problem D How Many Possibilities
撰写:Hacker_vision
题目大意:已知一个序列A1.A2….An,给你一个整数C,找到满足所有Ai+Aj==k的数对(i,j)的个数
题解:首先想到的是二分查找binary_search(),每次查询耗时O(nlogn),但由于查询次数较多会超时;不行的话就标记,开标记数组vis[j]记录整数j出现的次数,遍历所有元素a[i],累加vis[C-a[i]],注意数组越界的情况即可。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <climits>
#include <map>
#include <vector>
#include <list>
#include <stack>
#include <queue>
#define eps 1e-10
#define clr(k,v) memset(k,v,sizeof(k));
using namespace std;
typedef long long ll;
const int SZ = 1<<20;
const int maxn=2e3+10;
struct fastio{
char inbuf[SZ];char outbuf[SZ];fastio(){//??ä??ë??ä3ö1??
    setvbuf(stdin,inbuf,_IOFBF,SZ);
    setvbuf(stdout,outbuf,_IOFBF,SZ);
}}io;
int vis[maxn],a[maxn*maxn];
int main()
{
   //freopen("input.txt","r",stdin);
    int T;scanf("%d",&T);
    while(T--){
      clr(vis,0);
      int n;scanf("%d",&n);//cout<<"~!!!\n";
      for(int i=0;i<n;++i){
        scanf("%d",a+i);
        vis[a[i]]++;
      }
      sort(a,a+n);
      int Q;scanf("%d",&Q);
      while(Q--){
        int C;scanf("%d",&C);if(C>2000) {puts("0");continue;}//如果C太大,超过vis最大下标,会访问其他地址
        ll res=0;
        for(int i=0;i<n;i++){
         if(a[i]>C) break;    //数组越界,危险!
         if(a[i]==C-a[i]) res+=vis[C-a[i]]-1;
            else res+=vis[C-a[i]];
        }
        printf("%lld\n",res);
      }

    }
   return 0;
}

Problem H A + B ≥ K Problem
撰写:Hacker_vision
题目大意:已知一个序列A1.A2….An,给你一个整数K,找到满足所有Ai+Aj>=k的数对(i,j)的个数
题解:二分查找 STL库函数binary_search,lower_bound,upper_bound
BestCoder的改编题目,转化为A[j]>=k-A[i],在A[i]~A[n]中二分查找大于等于k-A[i]的第一个元素A[j],到数组末尾的所有元素都是所求解,累加起来即可。

sort(a,a+n);
★bool binary_search试图在已排序的[first, last)中寻找元素value。如果找到它会返回true,否则返回false,它不返回查找位置。
★iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素。(即返回的是地址)
★iterator upper_bound( const key_type &key ):返回一个迭代器,指向键值> key的第一个元素。(即返回的是地址)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <climits>
#include <map>
#include <vector>
#include <list>
#include <stack>
#include <queue>
#define eps 1e-10
#define clr(k,v) memset(k,v,sizeof(k));
using namespace std;
typedef long long ll;
const int SZ = 1<<20;
const int maxn=2e5+10;
struct fastio{
char inbuf[SZ];char outbuf[SZ];fastio(){//输入输出挂
    setvbuf(stdin,inbuf,_IOFBF,SZ);
    setvbuf(stdout,outbuf,_IOFBF,SZ);
}}io;
int n,k,a[maxn];
int main()
{
  // freopen("input.txt","r",stdin);
  while(scanf("%d%d",&n,&k)!=EOF){
    for(int i=0;i<n;i++) scanf("%d",a+i);
    sort(a,a+n);
    ll ans=0;
    for(int i=0;i<n;i++){
     ans+=n-(lower_bound(a+i+1,a+n,k-a[i])-a);
     //cout<<ans<<endl;
    }
    printf("%lld\n",ans);
   }
   return 0;
}

Problem J Can JM Bear Be happy?
撰写:Hacker_vision
题目大意:给你一个长度为n的字符串没判断字符串是否合法(即必须包含所有26个英文字母)
题解:标记数组vis[26]标记出现过的字母,注意预处理:字符串大小写转换

string s;
小写转换为大写:transform( s.begin(), s.end(), s.begin(), ::toupper );
大写转换为小写:transform( s.begin(), s.end(), s.begin(), ::tolower );

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <climits>
#include <map>
#include <vector>
#include <list>
#include <stack>
#include <queue>
#define eps 1e-10
#define clr(k,v) memset(k,v,sizeof(k));
using namespace std;
typedef int ll;
const int SZ = 1<<20;
const int maxn=2e3+10;
struct fastio{
char inbuf[SZ];char outbuf[SZ];fastio(){//输入输出挂
    setvbuf(stdin,inbuf,_IOFBF,SZ);
    setvbuf(stdout,outbuf,_IOFBF,SZ);
}}io;
string s;
bool vis[30];
int main()
{
  // freopen("input.txt","r",stdin);
   int n;
   while(scanf("%d",&n)!=EOF){
    cin>>s;
    transform(s.begin(),s.end(),s.begin(),::tolower);//cout<<s<<endl;
    clr(vis,false);
    for(int i=0;i<n;i++) vis[s[i]-'a']=true;
  //  puts(s);
    bool ok=true;
    for(int i=0;i<26;i++) if(vis[i]==false) {ok=false;break;}
    if(ok)puts("YES");else puts("NO");
   }
   return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值