date: 2019-07-28ios
给你两个不一样的整数A
和B
,要求你找到一个整数K
,同时知足|A-K|=|B-K|
。找不到时,输出"IMPOSSIBLE"
c++
聪明的读者读到这里确定已经发现了,这其实就是平均数,可是,要特判A
和B
的差是奇数的状况:此时K
不是整数,因此输出"IMPOSSIBLE"
。git
#include<bits/stdc++.h> using namespace std; int a,b; int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>a>>b; if((a+b)%2){//K不是整数 cout<<"IMPOSSIBLE"<<endl; }else{ cout<<(a+b)/2<<endl; } return 0; }
有一个长度为N
的序列,内部元素为1~N
。容许最多交换一次任意一对元素的位置,把这个序列变为升序(从小到大的)序列(能够选择不交换也就是交换零次,但最多一次),能够就输出"YES"
,不然输出"NO"
。算法
暴力。因为这道题的数据范围很小,因此只要模拟交换元素就好。数组
咱们跑一个二重循环表明交换的元素对,再在里面写一个循环判断是否有序便可。特殊地,咱们须要直接判断这个序列是否有序,由于题目里说能够不交换。优化
#include<bits/stdc++.h> using namespace std; int n; int a[55]; bool chk(){//检查序列是否有序 for(int i=1;i<=n;i++){ if(a[i]<=a[i-1]){//其实由于是1~n的序列,能够直接写a[i]!=i判断 return false; } } return true; } int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; } for(int i=1;i<n;i++){ for(int j=i+1;j<=n;j++){ swap(a[i],a[j]);//模拟交换位置 if(chk()){//有序了就输出 cout<<"YES"<<endl; return 0; } swap(a[i],a[j]);//check完记得换回来 } } if(chk()){//特殊地,判断数组一开始就有序的状况 cout<<"YES"<<endl; }else{ cout<<"NO"<<endl; } return 0; }
有N+1
座城市,而后其中的第i
个城市有A[i]
个怪兽在,有N
个英雄,第i
个英雄能够战胜在第i
和i+1
城市的怪兽,但第i
位英雄战胜的怪兽不超过B[i]
个。spa
贪心。显然地,因为第i
位英雄只能影响第i
和i+1
城市,因此i
以前的城市这位英雄都不能影响,因此尽可能让第i
位英雄战胜第i
座城市里的怪物,打不完B[i]
个在去下一座城市。code
若是第i
位英雄优先击杀第i+1
位的怪物,那么第1座城市可能会有结余,然后面的英雄由于本身的城市的怪物已经被杀掉一部分了,因此可能不能杀满B[i]
个,因此以前的作法应该是最优的。图片
#include<bits/stdc++.h> using namespace std; int n; int a[100005]; int b[100005]; long long ans; int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n; for(int i=1;i<=n+1;i++){ cin>>a[i]; } for(int i=1;i<=n;i++){ cin>>b[i]; } for(int i=1;i<=n;i++){//贪心的,让英雄先杀本身城市的怪物,再杀下一个城市的 if(b[i]<=a[i]){ ans+=b[i]; }else{ b[i]-=a[i]; ans+=a[i]; ans+=min(a[i+1],b[i]); a[i+1]-=min(a[i+1],b[i]); } } cout<<ans<<endl; return 0; }
给你一个字符串S
,包含0~9
和?
。在?
中填入0~9
,使得获得的数对13
取模余5
。ci
能够有前导零
DP。因为数据范围很大,有10^5
那么大,可是13
这个数字很小,是一个突破口。因而:
咱们创建一个二维数组DP
,DP[i][j]
表示计算到第i
位(第i
位尚未填入,此时i
从0
开始计算)时有多少种
对13
取模余j
的方法。正向思考,DP[i+1][(j*10+<填入的数字>)%13]+=DP[i][j]
,若是这一位是?
,那么填入的数字从1
到9
都要计算一遍。
#include<bits/stdc++.h> using namespace std; const int mod=1000000007; string s; int n; int dp[100005][15]; int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>s; int n=s.size(); dp[0][0]=1; for(int i=0;i<n;i++){ if(s[i]=='?'){ for(int j=0;j<13;j++){ for(int k=0;k<10;k++){//尝试填入0~9 dp[i+1][(j*10+k)%13]+=dp[i][j]; if(dp[i+1][(j*10+k)%13]>=mod)dp[i+1][(j*10+k)%13]-=mod;//常数优化 } } }else{ for(int j=0;j<13;j++){ dp[i+1][(j*10+s[i]-'0')%13]+=dp[i][j]; if(dp[i+1][(j*10+s[i]-'0')%13]>=mod)dp[i+1][(j*10+s[i]-'0')%13]-=mod;//常数优化 } } } cout<<dp[n][5]<<endl; return 0; }
其实这个常数优化并无什么用,由于计算下标时仍是须要取模。
我不会,因此就没有办法写了。
放张官方题解:
给你两个字符串s
和t
,问你是否有一个非负整数i
知足下列条件而且i
是有限的,若是是,那么求出i
的最大值。
条件:有一个非负整数j
,i
个t
链接起来是j
个s
链接起来的字串。
说人话(其实也是我比较喜欢的方式)就是给你两个串s
和t
,而后无限多个s
链接起来,是否能够找到有限个t
链接起来是s
的子串。若是无限多个t
都是字串,那么就输出-1
。
想法来自个人同窗。首先,你把足够多的s
链接起来,而后每个位置i
都查看s
从i
开始的后缀子串并记为s2
,查看t
是不是s2
的前缀。新开一个数组suf
记录是或否。而后,从后往前,作一个相似前缀和的操做,若是第i
位是1
,那么就加上第i+|t|
位的值(|t|
指t
的长度),能够在O(n)
时间内求出最长的连续的t
做为连续的s
的子串时,这个t
的连续的个数。
这个匹配操做,咱们可使用Hash
来把复杂度控制在O(n)
里(其实KMP
和Z算法
也能够实现)。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int mod=1145411919; const int p=810; //这么臭的哈希值应该没人会卡吧 string s,t; int ans; ll pw[16000005]; ll h[16000005]; ll ht[16000005]; int suf[16000005]; inline ll gh(int x){//求s中第x位开始的长|t|字符串的哈希值 if(x+t.size()>s.size())return -1; return (h[x+t.size()-1]-h[x-1]*pw[t.size()]%mod+mod)%mod; } int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>s>>t; while(s.size()<t.size()*2)s=s+s; s=s+s; s=s+s; s=s+s;//构建出足够长的s pw[0]=1; for(int i=1;i<=16000000;i++){ pw[i]=pw[i-1]*p%mod; }//预先求k的i次方,存入pw[i] h[0]=s[0]-'a'+1; for(int i=1;i<s.size();i++){ h[i]=(h[i-1]*p+s[i]-'a'+1)%mod; }//h[i]表明s到i的hash值 ht[0]=t[0]-'a'+1; for(int i=1;i<t.size();i++){ ht[i]=(ht[i-1]*p+t[i]-'a'+1)%mod; }//ht[i]表明t到i的hash值 for(int i=0;i<s.size();i++){ suf[i]=ht[t.size()-1]==gh(i); }//suf功用同上 for(int i=s.size()-t.size();i>=0;i--){ if(suf[i])suf[i]+=suf[i+t.size()]; ans=max(ans,suf[i]); }//和作法中解释的同样 if(ans+1>=s.size()/t.size()){ cout<<-1<<endl; return 0; }//判断t的链接是否过多,近似无限 cout<<ans<<endl; return 0; }
感谢你看完,若是你想支持我,你能够登陆帐号,把对个人建议和意见写在下面,帮助我取得进步。