A - こだわり者いろはちゃん / Iroha’s Obsession AtCoder - 1973
B - いろはちゃんとマス目 / Iroha and a Grid AtCoder - 1974
C - いっしょ / Be Together AtCoder - 2019
D - アンバランス / Unbalanced AtCoder - 2020
水题
题意的话可以“样例分析法”
#include
#define MAXN 10005
int N,K,digit[6],ans;
bool d[15];
int main()
{
scanf("%d %d",&N,&K);
int x,len=0;
for(int i=1;i<=K;i++)
{
scanf("%d",&x);
d[x]=1;
}
for(int i=N;i<=10000005;i++)
{
bool f=0;
x=i;
while(x)
{
if(d[x%10])
{
f=1;
break;
}
x/=10;
}
if(!f)
{
printf("%d\n",i);
return 0;
}
}
/*x=N;
while(x)
{
len++;
digit[len]=x%10;
x/=10;
}
bool f=0;
for(int i=1;i<=len;i++)
{
}*/
}
比较暴力(其实是很暴力),注意枚举的范围,应比MAXN大
非常好的一道题,很长,思维难度并不高,但是需要认真分析
Iroha and a Grid AtCoder - 1974【组合数学-乘法逆元-快速幂】【数学好题】
给出N个整数,把一个数变成另一个数的代价是(x-y)^2,求把这些数变成相同的数的最小代价。
刚开始的想法是把他们全部变成平均数(这可能就是直觉)
但是WA了(虽然样例能过)
然后就暴力枚举 范围也不大 个数和数的范围都才100
后来老师说他弄了一个什么很奇怪的函数,求了下导,然后算出来应该是在平均数的周围那3个数qwq
#include
#include
using namespace std;
#define MAXN 105
int N,ans=0x3f3f3f3f,cost;
int a[MAXN];
int Abs(int x)
{
if(x<0) return -x;
else return x;
}
int main()
{
bool f=0;
scanf("%d",&N);
for(int i=1;i<=N;i++)
{
scanf("%d",&a[i]);
if(i>1&&a[i]!=a[i-1]) f=1;
}
if(!f)
{
printf("0\n");
return 0;
}
sort(a+1,a+N+1);
for(int i=a[1];i<=a[N];i++)
{
cost=0;
for(int j=1;j<=N;j++)
cost+=Abs((a[j]-i)*(a[j]-i));
if(costprintf("%d\n",ans);
return 0;
}
我们称一个小写字母的序列是不平衡的当且仅当它的长度大于2,有一半的字母相同
给出一个字符串,找它的不平衡的子串
输出它的起始点和终止点的下标 如果没有,输出-1 -1
第一次的暴力做法TLE
#include
#include
using namespace std;
#define MAXN 100005
char s[MAXN];
int q[MAXN][30];
int main()
{
scanf("%s",s+1);
int len=strlen(s+1);
for(int i=1;i<=len;i++)
{
memcpy(q[i],q[i-1],sizeof(q[i]));
q[i][s[i]-'a']++;
}
for(int i=1;ifor(int j=i+1;j<=len;j++)
{
int tl=j-i+1;
for(int k=i;k<=j;k++)
{
int x=q[j][s[k]-'a']-q[i-1][s[k]-'a'];
if(x>tl/2)
{
printf("%d %d\n",i,j);
return 0;
}
}
}
printf("-1 -1\n");
return 0;
}
后来发现一个极其“优秀”的规律。
就是如果一个串存在不平衡的子串,那么它一定有一个长度为3的子串其中有两个字母是相同的(这个结论自己再琢磨琢磨,捯饬捯饬)
那反过来也是成立的,如果找不到一个长度为3的子串其中有两个字母是相同的,就说明没有解。(这个结论自己再琢磨琢磨,捯饬捯饬)
而且这题说随便出解,有SJ,那就线性查找有相邻的3个字母中有2个相同就输出结果。
若没有结果,就无解
#include
#include
using namespace std;
#define MAXN 100005
char s[MAXN];
int main()
{
scanf("%s",s+1);
int len=strlen(s+1);
for(int i=1;i<=len-1;i++)
{
if(s[i]==s[i+2])
{
printf("%d %d\n",i,i+2);
return 0;
}
if(s[i]==s[i+1])
{
printf("%d %d\n",i,i+1);
return 0;
}
}
printf("-1 -1\n");
return 0;
}
上面那种写法看起来和
if(s[i]==s[i+1]||s[i]==s[i+2])
是等价的,但是考虑边界的时候却不一样,如果这么写,在len-1和len相等的时候就会输出len 到len+1,非法!!!
在写程序的时候,注意循环边界,递归边界及递推边界等情况
但是后来改了之后发现,第3个点最后一个和倒数第二个相同,输出len-1,len可以过,输出len-1,len就不行。
OJ有BUG???