https://codeforces.com/contest/1263
A
题意
a b c >0两两-1,求最多减多少次
设 a<b<c 如果a+b>=c 则总可以化成 a+b=c||c+1,答案就是(a+b+c)/2
如果 a+b<c 则答案就是a+b
#include <stdio.h>
#include <algorithm>
using namespace std;
int a[5];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
for(int i=1;i<=3;i++)
scanf("%d",&a[i]);
sort(a+1,a+4);
if(a[1]+a[2]>=a[3])
printf("%d\n",(a[1]+a[2]+a[3])/2);
else
printf("%d\n",a[1]+a[2]);
}
}
B
https://codeforces.com/contest/1263/problem/B
题意输入10个4为数的0~9的密码,要求把相等的密码修改成不相等
因为只有10个密码,所以我们只需修改其中一位0~9遍历
#include <stdio.h>
#include <iostream>
#include <map>
#include <string>
using namespace std;
string s[19]; //用来存密码
map<string,int>mp; //查看哪些密码出现过
void change(string &s) //全局变量
{
for(char i='0';i<='9';i++)
{
s[0]=i;
if(!mp[s]) //没出现过这个数字
{
mp[s]=1;
break;
}
}
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
cin>>s[i];
mp.clear();
int ans=0;
for(int i=1;i<=n;i++)mp[s[i]]++;
for(int i=1;i<=n;i++)
{
if(mp[s[i]]>1)
{
mp[s[i]]--;
change(s[i]);
ans++;
}
}
printf("%d\n",ans);
for(int i=1;i<=n;i++)
std::cout << s[i] << std::endl;
}
}
C
https://codeforces.com/contest/1263/problem/C
if n=5, then the answer is equal to the sequence 0,1,2,5. Each of the
sequence values (and only them) can be obtained as ⌊n/k⌋ for some
positive integer k (where ⌊x⌋ is the value of x rounded down):
0=⌊5/7⌋, 1=⌊5/5⌋, 2=⌊5/2⌋, 5=⌊5/1⌋.
暴力做法是遍历每一个1~n+1 然后求出n/(i)不相等的答案
但我们会发现如n=100 i=26 27 28 ……33 n/i 都是等于3
有个技巧 i=n/(n/i)可以跳到
n/i(原)=n/i(新)的最远位置
即从26 跳到33
因为当n/i=k n%i==0 则i不变
n%i!=0 则n/k就等于最大的n/i=k
#include <stdio.h>
int ans[10000000];
int main()
{
int t,n;
int cnt;
scanf("%d",&t);
while(t--)
{
cnt=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)ans[++cnt]=n/i,i=n/(n/i);
printf("%d\n0",cnt+1);
for(int i=cnt;i;i--)
printf(" %d",ans[i]);
puts(" ");
}
}
https://codeforces.com/contest/1263/problem/D
题意
two passwords a and b are equivalent if there is a letter, that exists in both a and b;
two passwords a and b are equivalent if there is a password c from the list, which is equivalent to both a and b.
即如果 有一个字母和别人相等 这两个属于同一个集合abcd……xyz包括所有集合
/*
这题难点就是如何将a b ab他们属于同一个集合 ,且计数为1,即后面加入的
字符串会影响之前的集合
*/
#include <stdio.h>
int fa[28],a[28],n,cnt;
char s[55];
int find(int x)
{
return x==fa[x]?x:fa[x]=find(fa[x]);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=26;i++)fa[i]=i;
while(n--)
{
scanf("%s",s);
for(int i=0;s[i];i++)a[s[i]-'a'+1]=1; //出现字母,即不合并有多少集合
for(int i=1;s[i];i++) //cnt =合并的次数
{
int p=find(s[i]-'a'+1),q=find(s[i-1]-'a'+1);
if(p!=q)fa[p]=q,cnt++; //出现新的字母,并放入同一个集合
} //某个字符串如果与之前的都不交叉,则
} //独立出来
for(int i=1;i<=26;i++)cnt-=a[i]; //独立出来的个数 =不合并-合并的次数
printf("%d",-cnt);
}