A题:https://codeforces.com/contest/1263/problem/A
题意:这道题的话,他给你三种糖果,每种糖果有r,g,b颗,然后你每天只吃2种糖果,但是这两种糖果是不同的,你不能吃相同的糖果。
思路:推导一下的话,因为这三种糖果的颗数不同,也没有什么特别的规律,所以我们就把它排序,从小到大。现在顺序是r<g<b。如果r+g<b,那么只能吃r+g天;要是r+g>b的话,就可以是 (r+g+b)/2 天。
AC代码:
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
ll a[5];
int main()
{
int t;
cin>>t;
while(t--)
{
for(int i=1;i<=3;i++)
cin>>a[i];
sort(a+1,a+4);
cout<<min(a[1]+a[2],(a[1]+a[2]+a[3])/2)<<endl;
}
return 0;
}
B题:https://codeforces.com/contest/1263/problem/B
题意:这道题的话,是给你很多个PIN码,每个PIN码是四位,然后每个PIN码可能是相同的,也可能是不同的,问你最少需要多少次,可以把给你的PIN码都变成不同的,每次可以改变一个PIN码的一位数。
思路:思路的话,因为n<10,所以我们很容易就想到最多需要10次来改变这个PIN码,而且每个PIN码都可以改变,所以就判断一下,如果需要改变,依次改变下去就好了。
AC代码:
#include <bits/stdc++.h>
using namespace std;
string s[20];
int n;
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n;
map<string,int>q;
for(int i=0; i<n; i++)
{
cin>>s[i];
q[s[i]]++;
}
int ans=0;
for(int i=0; i<n; i++)
{
if(q[s[i]]==1)
continue;
ans++;
q[s[i]]--;
for(char j='0'; j<='9'; j++)
{
s[i][0]=j;
if(q[s[i]]==0)
{
q[s[i]]++;
break;
}
}
}
cout<<ans<<endl;
for(int i=0; i<n; i++)
cout<<s[i]<<endl;
}
return 0;
}
C题:https://codeforces.com/contest/1263/problem/C
题意:这道题的话,初看这道题,是给你一个数,找到它从1到它本身的所有除数,而且除数要四舍五入到最低(且不能重复)。
思路:然后很容易就想到枚举1~n,但这样做的话就t了,因为范围是1~10^9。
所有我们用到分块的思想,推导样例,会发现n/i和n/(n/i)所得的数是一样的,而且还能减少枚举次数,优化时间复杂度。
然后因为输出的时候是从小到大输出。
所以我们用栈的特点,后进先出,这样可以实现从小到大输出。
关于分块,可以看看这篇文章:https://blog.csdn.net/gdhy9064/article/details/90112836
AC代码:
#include <bits/stdc++.h>
typedef long long ll;
const int maxx=1010;
const int inf=0x3f3f3f3f;
using namespace std;
int main()
{
ll t,n;
cin>>t;
while(t--)
{
cin>>n;
stack<ll>q;
ll ans=0;
for (ll i=1; i<=n; i=ans+1)
{
if(n/i!=0)
ans=min(n,n/(n/i));
q.push(n/i);
}
cout<<q.size()+1<<endl;
cout<<0<<" ";
while(!q.empty())
{
cout<<q.top()<<" ";
q.pop();
}
cout<<endl;
}
return 0;
}
D题:https://codeforces.com/contest/1263/problem/D
题意:这道题的话,给你一些字符串,它们是进入系统的密码。而且它们之间有转化关系,比如a=b,那么a,b,ab都是相等的,若a=c,那么c=b。现在给你n个字符串,找到最少需要几次才能使用这些字符串来进入系统。
思路:这道题的大概思路就是,因为字母之间有对应的转化关系。所以我们用并查集来维护这个查找,把n个字符串中,是a的对应在一起,是b的对应在一起。依次对应,看看有多少个对应,就是题意要求的最少需要几次的数量。
AC代码:
#include <bits/stdc++.h>
typedef long long ll;
const int maxx=300010;
const int inf=0x3f3f3f3f;
using namespace std;
int n;
int pre[maxx];
string s[maxx];
int getf(int x)
{
if(x==pre[x])
return x;
pre[x]=getf(pre[x]);
return pre[x];
}
int main()
{
cin>>n;
for(int i=1; i<=n; i++)
{
cin>>s[i];
}
for(int j=1; j<=n+26; j++)
{
pre[j]=j;
}
for(int i=1; i<=n; i++)
{
for(int j=0; j<s[i].size(); j++)
{
pre[getf(i)]=pre[getf(n+s[i][j]-'a'+1)];
}
}
int ans=0;
set<int>vis;
for(int i=1; i<=n; i++)
{
if(!vis.count(getf(i)))
{
ans++;
vis.insert(getf(i));
}
}
cout<<ans<<endl;
return 0;
}