目录
B Element Swapping
E Sequence in the Pocket
F Abbreviation
G Lucky 7 in the Pocket
H Singing Everywhere
I Fibonacci in the Pocket
J Welcome Party
K Strings in the Pocket
【题意】已知交换前数列的x,y,该数列某两个位置互换后得到给定数列,根据x,y计算现数列由原序列交换位置的方案数。
【解题思路】推公式题。将原序列的x,y值设为x1,y1,现序列的x,y值设为x2,y2,设互换了p,q两个位置,易得以下两个等式dx=x2-x1=(p-q)(ap-aq)与dy=y2-y1=(p-q)(ap^2-aq^2),两式联立后易得dy=dx*(ap+aq),所以遍历一遍数组,对于每个树都能得到一个可以与她交换的数,再判断一下是否成立即可。对啦dx==0 &&dy==0的情况是只要数列中相同的数交换都可以,记得一定要特判,不然一直浮点错误。
【代码】
#include
using namespace std;
const int maxn=1e5+100;
typedef long long LL;
LL a[maxn],tot[maxn],c[maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
LL x1=0,y1=0,x2=0,y2=0,ans=0;
memset(tot,0,sizeof(tot));
scanf("%d%lld%lld",&n,&x1,&y1);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
tot[a[i]]++;
x2+=1LL*i*a[i];
y2+=1LL*i*a[i]*a[i];
}
LL dx=x2-x1,dy=y2-y1;
if(dx==0 && dy==0)
{
for(int i=1;i<=100000;i++)
{
if(tot[i]>1)
ans+=(tot[i]*(tot[i]-1))/2LL;
}
}
else if(dx!=0 && dy!=0)
{
if(dy%dx==0)
{
LL p=dy/dx;
for(int i=1;i<=n;i++)
{
if(a[i]i&& q<=n&&a[q]==p-a[i])ans++;
}
}
}
}
}
printf("%lld\n",ans);
}
}
【题意】给一个长度为n的数组,每次操作可以把一个数放到最前面,问最少几次操作可以使这个数组变成非递减数列。
【解题思路】签到题,排序后倒序查找即可。
【代码】
#include
using namespace std;
const int maxn=1e5+5;
int a[maxn],b[maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int cnt=0,n;
scanf("%d",&n);
for(int i=0;i=0;i--)
{
if(a[i]==b[t])
{
t--;
cnt++;
}
}
printf("%d\n",n-cnt);
}
}
【题意】除单词的首字母外,去除原因字母。
【解题思路】签到题。
【代码】
#include
using namespace std;
const int maxn=1e5+5;
char a[maxn],b[maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
string s1,s2;
cin>>s1;
s2=s1[0];
for(int i=1;i
【题意】找一个大于等于n的,能被7整除但不能被4整除的最小整数。n<=100。
【解题思路】签到题。
【代码】
#include
using namespace std;
const int maxn=1e5+5;
char a[maxn],b[maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
for(int i=n;i<=500;i++)
{
if(i%7==0 && i%4!=0)
{
printf("%d\n",i);
break;
}
}
}
}
【题意】给n个数,最多可以删去一个数使这个数列中的峰值出现次数最少。
【解题思路】签到题。先把峰值位置都找出来,分类讨论一下即可。
(1)当峰值位置只相隔1个位置时,且两个峰值一样大时,删去中间那个数达到最优,ans-2。
(2)其余只要判断一下前后的大小关系,最多只可能-1。
【代码】
#include
using namespace std;
const int maxn=1e5+5;
long long a[maxn],b[maxn];
vectorv;
int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
v.clear();
scanf("%d",&n);
for(int i=0;ia[i-1] && a[i]>a[i+1])v.push_back(i);
}
int ans=v.size(),f=0;
if(v.size()>=1)
{
for(int i=0;it3)
{
if(v[i]-2>=0)
{
int t0=a[v[i]-2];
if(t0
【题意】求斐波那契数列的第a到第b项和为奇数还是偶数。
【解题思路】签到题。因为斐波那契数列的特征是奇 奇 偶 奇 奇 偶……即3的倍数即为偶数,所以只需要判断a和b被3除的情况即可。不需要大数,只需要将该数的每一位加起来除3即可。
【代码】
#include
using namespace std;
const int maxn=1e5+5;
char a[maxn],b[maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%s%s",a,b);
int suma=0,sumb=0,la=strlen(a),lb=strlen(b);
for(int i=0;i
【题意】有n个人,m对朋友,如果某个人的一个朋友已经进去了,那么他就不会不开心,如果里面一个朋友都没有,他就会不开心,求最少的不开心人数以及进入的最小序列(然而比赛的时候读成一个人只有当它的所有朋友进去了他才会开心……)。
【解题思路】并查集找一下连通块,连通块个数即为答案,再用优先队列维护一下即可输出最小序列。(坑点是卡时间……)
【代码】
#include
using namespace std;
const int maxn=1e6+5;
int pre[maxn],vis[maxn],n,m,ans,ans1[maxn],tot;
vectorv[maxn];
int findroot(int x)
{
return pre[x]==x?x:pre[x]=findroot(pre[x]);
}
void bfs()
{
priority_queue,greater >pq;
for(int i=1;i<=n;i++)
{
if(pre[i]==i)
{
ans++;
pq.push(i);
vis[i]=1;
}
}
while(!pq.empty())
{
int t=pq.top();
pq.pop();
ans1[tot++]=t;
for(int i=0;i
【题意】给一个字符串s和t,询问s的子串翻转后得到t的方案数。
【解题思路】当s和t相等时,需要用马拉车算法,马拉车算法用于求字符串的回文串,p[i]表示以位置i为中心的回文串的长度;当s和t不相等时,设置指针l和r,分别找到第一个s字符串和t字符串中s[l]和t[l]、s[r]和t[r]不等的位置,然后一直往外扩即可。
【代码】
#include
using namespace std;
typedef long long LL;
const int maxn=2e6+5;
LL p[maxn*2];
LL ans;
int len;
char s[maxn],tmp[maxn*2],t[maxn];
/*
void init()
{
int len=2;
ts[0]='$';
ts[1]='#';
for(int i=0;i=0 && r