题目:
解题思路:
对于总共有n个宝石,统计出不同的宝石有a个,从后往前取,则第一次取宝石可以取出a个不同的宝石,剩下不同的宝石有b个(b<=a),第二次再取出b个不同的宝石······最终统计一下次数即可。
代码如下:
#include
#include
#define int long long
#define endl '\n'
using namespace std;
signed main()
{ ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--)
{
int n,a[200005],sum=0,ans=0,k=0,j=0;
mapb;
mapc; //这里使用数组会超时,所以要考虑stl容器
cin>>n;
for(int i=1;i<=n;i++)
{cin>>a[i];
if(b[a[i]]==0)sum++; //统计不同宝石的总个数
b[a[i]]++;} //统计每个宝石的个数
for(int i=n;i>=1;i--)
{
if(c[a[i]]==0)k++; //统计不同宝石的个数
c[a[i]]++;
b[a[i]]--;
if(b[a[i]]==0)j++; //每当有宝石的个数为0时,总数要减去1
if(k==sum)
{sum-=j,j=0,ans++,k=0;
c.clear(); //清空}
}
cout<
题目:
解题思路:
此题可以直接暴力搜索,对a,b,c,d,_,进行整体考虑,最终会求出一个密码x,若满足题目所给条件及范围,则数量+1。
代码如下:
#include
#include
#define int long long
#define endl '\n'
using namespace std;
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--)
{
int n,y;
string s;
cin>>n;
cin>>s>>y;
int len=pow(10,n-1); //求出这个位数的最小值,比如n=3时,最小值是100
if(n==1)len=0;
mapk;
for(int a=0; a<=9; a++)
{
for(int b=0; b<=9; b++)
{
for(int c=0; c<=9; c++)
{
for(int d=0; d<=9; d++)
{
if(a==b||a==c||a==d||b==c||b==d||c==d)continue; //a,b,c,d不能相同
for(int _=0; _<=9; _++)
{
int x=0;
for(int i=0; i='0'&&s[i]<='9')x=x*10+s[i]-'0';
else if(s[i]=='a')x=x*10+a;
else if(s[i]=='b')x=x*10+b;
else if(s[i]=='c')x=x*10+c;
else if(s[i]=='d')x=x*10+d;
else x=x*10+_;
if(x>=len&&x<=y&&x%8==0) //若满足题目条件
k[x]=1;
}
}
}
}
}
}
cout<
题目:
(T组测试数据)
(表示完全图G的顶点数量)
(表示完全图G的每个顶点的值)
第二组测试数据:
3 10 1 100
解题思路:
对于此题使用最短路会超时,所以要先找规律,边权值为取两个点之间权值较大的那个权值的两倍。以下对第二组数据进行分析:
题目所求解为1->2,1->3,2->3,2->1,3->1,3->2,对此只需要求出前一半的值最后再乘上2就可以。接下来再对前一半进行分析:首先要对顶点进行排序,1->2取值为20,1->3取值为200,2->3取值为200,总结得顶点1的次数为0,顶点2的次数为1,顶点3的次数为2,得到公式sum+=a[i]*(i-1)*2;
代码如下:
#include
#include
#define int long long
#define endl '\n'
using namespace std;
signed main()
{ ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--)
{
int n,a[200005],sum=0;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1);
for(int i=n;i>=2;i--)
sum+=a[i]*(i-1)*2;
cout<
题目:
解题思路:
此题与上一题解法类似,只不过边权值为取两个点之间权值较小的那个权值的两倍。
对样例分析得到1->3取值有两种情况,一是直接取值,另一个是经过最小值点。
代码如下:
#include
#include
#define int long long
#define endl '\n'
using namespace std;
signed main()
{ ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--)
{
int n,a[200005],sum=0;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1);
for(int i=1;i