第一题
首先i,j都等于0,i++
这时sum=3+3大于我们给出的数,所以让j++。注意这里不能减a[i]要减a[j]
以此类推 ,当两个指针处于这个位置时,距离就已经最大了
如果你头铁硬是要开int也可以,就如下图
还有这里记数一定要定义为-1,我是傻逼
代码如下
#include <iostream>
using namespace std;
const long long N = 100000010;
long long a[N], sum,ans=-1;
inline long long read()
{
char c = getchar();
long long n = 0;
while (c < '0' || c > '9')
{
c = getchar();
}
while (c >= '0' && c <= '9')
{
n = (n << 1) + (n << 3) + (c & 15);
c = getchar();
}
return n;
}
int main()
{
long long n,m;
n=read(),m=read();
for(long long i=0,j=0;i<n;i++)
{
a[i]=read();
sum+=a[i];
while(sum>m) sum-=a[j++];
if(sum==m) ans=max(ans,i-j+1);
}
cout<<ans<<endl;
return 0;
}
第二题就是dfs next_permutation永远滴神
不知道说啥,直接贴
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
//const int N = 1000010;
ULL a[1000010];
LL ans; //
LL sum; //这两个我真不知道为啥不能写一起,写一起直接不让过
int main()
{
ULL n, m;
cin >> n >> m;
for (ULL i = 0; i < n; i++)
{
a[i] = i;
sum = sum * 10 + a[i];
}
if (sum % m == 0)
ans++;
while (next_permutation(a, a + n))
{
sum = 0;
for (ULL i = 0; i < n; i++)
sum = sum * 10 + a[i];
if (sum % m == 0)
ans++;
}
if (ans)
cout << ans << endl;
else
cout << "-1" << endl;
return 0;
}
第3题
这题就是前缀和
#include <iostream>
using namespace std;
const int N=1000010;
int a[N],b[N];
int main()
{
int n,k; //n是个数,k是查询的次数
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) b[i]=b[i-1]+a[i];
while(k--)
{
int l,r;
cin>>l>>r; // l和r是查询区间
cout<<b[r]-b[l-1]<<endl;
}
return 0;
}
第4题
思路:二分
#include <iostream>
using namespace std;
typedef unsigned long long Ull;
typedef long long LL;
const int N = 1000010;
Ull a[N];
int n, m;
bool chakan(int m, Ull x)
{
int ans = 1;
Ull sum = 0;
for (int i = 0; i < n; i++)
{
if (a[i] > x)
return false;
if (sum + a[i] <= x)
sum += a[i];
else
sum = a[i], ans++;
}
if (ans <= m)
return true;
return false;
}
int main()
{
cin >> n >> m;
Ull l = 1, r = 0;
for (int i = 0; i < n; i++)
{
cin >> a[i];
r = r + a[i];
}
while (l < r)
{
Ull mid = l + r >> 1;
if (chakan(m, mid))
r = mid;
else
l = mid + 1;
}
cout << r << endl;
return 0;
}
第5题
这题我赛场代码一直过不了(赛场上忘记判断),我都无语了,也不想重写,直接死了
我是傻逼
简单说一下吧。
和高精度除法差不多一个意思,要除去高位0
列如:213
k=2
那么最小的就是把2和3删掉剩下的一个1
///错误代码
#include <iostream>
#include <queue>
using namespace std;
int main()
{
ios::sync_with_stdio;
cin.tie(0);
cout.tie(0);
string s;
int len, shanchu;
cin >> s;
len = s.length();
cin >> shanchu;
for (int i = 0; i < shanchu; i++)
{
len = s.length();
for (int j = 0; j < len; j++)
{
if (s[j + 1] < s[j])
{
s.erase(j, 1);
break;
}
}
}
int i = 0,j;
while (i < s.length() && s[i] == '0')
{
i++;
}
for ( j = i; j < s.length(); j++)
{
cout << s[j];
}
if(i==j)
{
cout<<'0'<<endl;
}
return 0;
///错误代码
}
我人都傻了,一直段错误,一直加0
#include <stdio.h>
#include <string.h>
const int N = 100000010;
char s[N];
int k,i,j=1;
int main()
{
scanf("%s%d", s,&k);
//while(k--)
//{
//for(i=0;i<sizeof(s)/sizeof(s[0])&&s[j-1]>0;i++)
for(;s[j-1]>0;)
{
if(k<=0||s[i]<=s[j])
{
s[++i]=s[j++];
}
else i--,k--;
}
//}
int len = strlen(s);
for(i = 0; s[i] == '0' && i < len - 1; i++); //去0
printf("%s", s + i);
return 0;
}
第6题
我看到这题直接没脑子,数据都没看直接打
错误代码
#include<iostream>
using namespace std;
typedef unsigned long long ULL;
const int N=10000010,M=3000000;
int a[N],son[M][2];
int n,idx;
void charu(int x)
{
int p=0;
for(int i=30;~i;i--)
{
int &s=son[p][x>>i&1];
if(!s) s=++idx;
p=s;
}
}
int chazhao(int x)
{
int p=0,res=0;
for(int i=30;~i;i--)
{
int s=x>>i&1;
if(son[p][!s])
{
res+=1<<i;
p=son[p][!s];
}
else p=son[p][s];
}
return res;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
a[i]=i;
}
for(int i=1;i<=n;i++) charu(a[i]);
int res=0;
for(int i=0;i<n;i++) res=max(res,chazhao(a[i]));
cout<<res<<endl;
return 0;
}
AC代码
简单来说就是找这个数的2进制有多少位,然后把它左移多少位
1ll是因为数据太大了
#include<iostream>
#include<cmath>
#include<iostream>
typedef long long LL;
using namespace std;
LL n;
int main()
{
cin >> n;
int c = log2(n) + 1;
cout << (1ll << c) - 1 << endl;
return 0;
}
第7题
emmmm,同上赛场上直接死掉
起始很简单的一题,给我想复杂了我以为A%l%%a%n也算,我是傻逼
#include<iostream>
using namespace std;
string a;
int n,ans;
int main(){
cin>>n;
cin.ignore();
for(;n;n--){
string b;
bool flag=false;
int sum=0;
getline(cin,a);
for(int i=0;i<a.size();i++){
if(a[i]!=' ') b+=a[i];
if(a[i]=='%') sum++;
}
if(b.find("Alan")<b.size()) flag=true;
if(flag) ans+=sum;
}
cout<<ans;
return 0;
}
H&I就是在结构体里面比较然后输出
#include <iostream>
#include <string.h>
#include <cmath>
#include<algorithm>
using namespace std;
const int N=100000010;
struct card{
char s[30];
char m[30];
char x[30];
char h[30];
int idx;
}a[N]; //H这题把N开101
bool cmp(card x,card y){
int n = strlen(x.s);
int m = strlen(y.s);
if(n!=m)return n<m;
else {
for(int i = 0;i<n;++i){
if(x.s[i]!=y.s[i])return x.s[i]<y.s[i];
}
}
return x.idx<y.idx;
}
int main(){
int n;
cin>>n;
for(int i = 1;i<=n;++i){
scanf("%s %s %s %s",a[i].s,a[i].m,a[i].x,a[i].h);
a[i].idx = i;
}
sort(a+1,a+n+1,cmp);
for(int i = 1;i<=n;++i){
printf("%s %s %s %s\n",a[i].s,a[i].m,a[i].x,a[i].h);
}
return 0;
}
J就是纯签到题目 找到这组数的最小值然后找到这个数的下标