文章目录
题目:[The Smallest String Concatenation]
(http://codeforces.com/problemset/problem/632/C)
题意:就是给你n个字符串,每个字符串长度不超过50,问你把这些字符串拼接在一起使它的字典序最小。
思路:一开始就以为是一个普通的字符串排序,利用sort的重载,后来发现存在一些问题,就是当字符串为x, xxa, xxz,的时候排序结果跟样例不一样后来发现,当某个串为另一个串的子串的时候会出现问题。所以就想到在sort的重载改一下条件,把两个字符串拼接在一起。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5*1e4+10;
bool cmp(string a, string b){//重载排序
return a+b < b+a;//拼接的方法
}
string a[maxn];
int main(){
int n;
ios::sync_with_stdio(false);
cin>>n;
for(int i = 0; i < n; i++){
cin>>a[i];
}
sort(a, a+n, cmp);
for(int i = 0; i < n; i++){
cout<<a[i];
}
cout<<endl;
return 0;
}
题目:Longest k-Good Segment
题意:给你一个长度为n的字符串,然后让你求出不大于k个不同的数的区间范围l和r。
思路:通过双端队列去维护,用vis数组标记这个数在不在双端队列中,用cn来记录双端队列中不同数的个数。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;
int vis[maxn], a[maxn];
deque<int>q;
int main()
{
int n, k;
scanf("%d %d", &n, &k);
for(int i = 0; i < n; i++)scanf("%d", &a[i]);
while(q.size())q.pop_back();
int ans = 0, l, r, cn = 0;
memset(vis, 0, sizeof(vis));
for(int i = 0; i < n; i++)
{
if(!vis[a[i]])cn++;//如果没有被标记过,不同数的个数加1
vis[a[i]]++;//标记一下
q.push_back(i);
while(q.size() && cn > k)//如果不同数的个数大于k弹出队首的数
{
int t = q.front();
vis[a[t]]--;
if(!vis[a[t]])cn--;//如果这个数所有标记的都清空了,那么cn--;
q.pop_front();
}
if(q.size() && ans < i-q.front()+1)//更新最大范围
{
ans = i-q.front()+1;
l = q.front()+1;//因为从0开始的所以l, r加1
r = i+1;
}
}
printf("%d %d\n", l, r);
return 0;
}
题目:Mr. Kitayuta’s Colorful Graph
题意:本题的题意就是给你一个无向图,n个点, m条边,然后路径是ai–bi,路的颜色是wi.
然后经过q次查询,问你ui—vi这条边之间间接或者直接有多少中颜色,每一种路颜色必须一样。
思路:dfs+暴力
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000;
int ne[maxn], e[maxn], h[maxn], w[maxn], tot = 0;
int vis[maxn], flag[maxn], ans = 0, res = 0;
void add(int u, int v, int val)//链式前向星存图
{
e[tot] = v;
w[tot] = val;
ne[tot] = h[u];
h[u] = tot++;
}
void dfs(int u, int v, int val)//u是起点,v是重点,val是路的颜色。
{
if(u == v)
{
ans = 1;
return;
}
vis[u] = 1;
for(int i = h[u]; ~i; i = ne[i])
{
int t = e[i];
if(!vis[t] && w[i] == val)
{
vis[t] = 1;
dfs(t, v, val);
vis[t] = 1;
}
}
}
int main()
{
int n, m;
scanf("%d %d", &n, &m);
memset(h, -1, sizeof(h));
for(int i = 0; i < m; i++)
{
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
add(u, v, w);
add(v, u, w);
}
int q, u, v;
scanf("%d", &q);
for(int i = 0; i < q; i++)
{
res = 0;
scanf("%d %d", &u, &v);
memset(flag, 0, sizeof(flag));//用来保存该颜色是否已经存在
for(int j = h[u]; ~j; j = ne[j])
{
ans = 0;
memset(vis, 0, sizeof(vis));
dfs(u, v, w[j]);
if(flag[w[j]])continue;
res += ans;
flag[w[j]] = 1;
}
cout<<res<<endl;
}
return 0;
}