100+40+100=240
为毛t3正解了, t2才40?
T1.名字排序(name)
【问题描述】
给定 n 个字符串,请去重后按照字典序排序
【输入格式】 从文件 name.in中读入数据。 输入的第一行包含两个正整数 n 表示总数
,接下来 n行有 n 个字符串。
【输出格式】
第一行输出去重后的字符串个数 X
接下来 x 行按照字典序输出每一个字符串
【样例 1 输入】
4
a
ab
cdef
ejdeh
【样例 1 输出】
4
a
ab
cdef
ejdeh
对于 20%的数据保证不需要去重
对于 100%的数据 n<=100000;单个字符串长度小于 10。
水题(划掉),STL搞一搞就好啦。qwq
1.字符串排序自动为字典序,无需定义。
2.巩固了一下STL。
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
#include<vector>
using namespace std;
vector<string> a;
string aa;
int ans,n;
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)cin>>aa,a.push_back(aa);
sort(a.begin(),a.end());
vector<string>::iterator new_end;
new_end=unique(a.begin(),a.end());
for(vector<string>::iterator i=a.begin();i!=new_end;i++)ans++;printf("%d\n",ans);
for(vector<string>::iterator i=a.begin();i!=new_end;i++)cout<<*i<<endl;
}
另一种水法——Taunt大佬
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxn = 100000 + 100;
string ch[maxn];
int n,ans = 0;
int main() {
scanf("%d",&n);
for(int i = 1; i <= n; i++) cin>>ch[i];
sort(ch+1,ch+1+n);
for(int i = 1; i <= n; i++)
if(ch[i] != ch[i-1]) ans++;
cout<<ans<<endl;
for(int i = 1; i <= n; i++) {
if(ch[i] == ch[i-1]) continue;
cout<<ch[i]<<endl;
}
return 0;
}
超快的水法
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct rt
{
char a[20];
};
rt que[100001];
bool cmp(rt x,rt y)
{
int judge;
judge=strcmp(x.a,y.a);
if(judge<0) judge=1;
else judge=0;
return judge;
}
int main()
{
int n,ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%s",que[i].a);
sort(que+1,que+n+1,cmp);
for(int i=1;i<=n;i++)
{
if(strcmp(que[i-1].a,que[i].a)==0) continue;
else ans++;
}
printf("%d\n",ans);
for(int i=1;i<=n;i++)
if(strcmp(que[i-1].a,que[i].a)==0) continue;
else printf("%s\n",que[i].a);
return 0;
}
T2.大吉大利(jiry)
【问题描述】
“大吉大利,晚上吃鸡!”
牛牛最近迷上了《绝地求生 大逃杀》这款游戏。他恨不能每天都吃鸡。但是他的舍友还
在王者峡谷等着他开黑。然而牛牛的心中只有一件事,那就是学习。
现在共有 n 天,每天都有一个数字 i,具体含义如下:
0 牛牛不能吃鸡也不能玩农药
1 牛牛可以吃鸡但不能玩农药
2 牛牛不可以吃鸡但可以玩农药
3 牛牛可以吃鸡或者玩农药
每天只能选择吃鸡、玩农药、学习中的一件事,并且牛牛不能连续两天吃鸡也不能连续两
天玩农药。请求出牛牛最大的学习的总天数。
【输入格式】 从文件 jiry.in中读入数据。 输入的第一行包含两个正整数 n 表示总天数。
接下来 n 行,每行包含 1个数字 i
【输出格式】输出到文件 jiry.out 中。输出一个牛牛最多学习的总天数。
【样例 1 输入】
7
1 3 3 2 1 2 3
【样例 1 输出】
0
【样例 2 输入】
2
2 2
【样例 2 输出】
1
【样例 3 输入】
4
1 3 2 0
【样例 3 输出】
2
//改编题,来自cf698A
我的贪心(40)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
using namespace std;
const int maxn=101;
int a[maxn],n,ans;
int main()
{
scanf("%d",&n); a[0]=233;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int x=1; while(a[x]==3) x++;
for(int i=x;i<=n;i++)if(a[i]==3){
if(a[i-1]==1) a[i]=2;
if(a[i-1]==2) a[i]=1;
}
for(int i=x;i<=n;i++) if((a[i]==0)||(a[i]==a[i-1])) ans++;
printf("%d",ans);
}
改(100):
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=101;
int a[maxn],ans,n;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++){
if(a[i]==0) ans++;
else if(a[i]==a[i-1]&&a[i]!=3) ans++,a[i]=0;
else if(a[i]==3){
if(a[i-1]==0||a[i-1]==3) a[i]==0;
else if(a[i-1]==1) a[i]=2;
else if(a[i-1]==2) a[i]=1;
}
}
printf("%d",ans);
return 0;
}
DP:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 233;
int n,f[maxn][10]; // 0 study 1 wangzhe 2 ji
int read() {
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9') {
if(ch == '-') f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + ch - '0';
ch = getchar();
}
return x * f;
}
int main() {
n = read();
for(int i = 0; i <= n; i++) {
for(int j = 0; j <= 2; j++)
f[i][j] = 1<<29;
}
f[0][0] = 0;
for(int i = 1; i <= n; i++) {
int a = read();
if(a == 1 || a == 3) {
f[i][2] = min(f[i - 1][1], f[i][2]);
f[i][2] = min(f[i - 1][0], f[i][2]);
}
if(a == 2 || a == 3) {
f[i][1] = min(f[i - 1][2], f[i][1]);
f[i][1] = min(f[i - 1][0], f[i][1]);
}
f[i][0] = min(f[i - 1][2] + 1,f[i][0]);
f[i][0] = min(f[i - 1][0] + 1,f[i][0]);
f[i][0] = min(f[i - 1][1] + 1,f[i][0]);
}
int ans = 1<<29;
ans = min(ans,f[n][0]);
ans = min(ans,f[n][1]);
ans = min(ans,f[n][2]);
cout<<ans<<endl;
return 0;
}
电话线(line)
多年以后,笨笨长大了,成为了电话线布置师。由于地震使得某市的电话线全部损坏,笨笨
是负责接到震中市的负责人。该市周围分布着 N(1<=N<=1000)根据 1……n 顺序编号的废弃
的电话线杆,任意两根线杆之间没有电话线连接,一共有 p(1<=p<=10000)对电话杆可以拉
电话线。其他的由于地震使得无法连接。
第 i 对电线杆的两个端点分别是 ai,bi,它们的距离为 li(1<=li<=1000000)。数据中每对
(ai,bi)只出现一次。编号为 1的电话杆已经接入了全国的电话网络,整个市的电话线全都
连到了编号 N 的电话线杆上。也就是说,笨笨的任务仅仅是找一条将 1 号和 N 号电线杆连起
来的路径,其余的电话杆并不一定要连入电话网络。
电信公司决定支援灾区免费为此市连接 k 对由笨笨指定的电话线杆,对于此外的那些电话
线,需要为它们付费,总费用决定于其中最长的电话线的长度(每根电话线仅连接一对电话
线杆)。如果需要连接的电话线杆不超过 k 对,那么支出为 0.
请你计算一下,将电话线引导震中市最少需要在电话线上花多少钱?
输入输出格式
输入格式:
输入文件的第一行包含三个数字 n,p,k;
第二行到第 p+1行,每行分别都为三个整数 ai,bi,li。
输出格式:
一个整数,表示该项工程的最小支出,如果不可能完成则输出-1.
输入输出样例
输入样例#1:
5 7 1
1 2 5
3 1 4
2 4 8
3 2 3
5 2 9
3 4 7
4 5 6
输出样例#1:
4
//usaco原题
正解是二分+spfa最短路
本来想写二分+去环lca的,模拟了一下果断gg
具体的,套俩模板就好了,
1.二分答案l=0,r=max(最长边)
2.spfa跑mid,找出最短路径里,第k+1大的边与二分答案的关系,return调整边界就好(细节就是把大于二分答案的边看做1,小于二分答案的边看做0)
3.别把二分跑死循环了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
const int maxn=1e3+10;
const int maxp=1e4+10;
const int maxl=1e6;
const int inf=1<<29;
int n,p,k,li,ri,mid,ans,head[maxn],tot,dis[maxn],vis[maxn];
int read(){
int t=1,x=0; char ch=getchar();
while(ch>'9'||ch<'0'){ if(ch=='-')t=-1; ch=getchar(); }
while(ch<='9'&&ch>='0'){ x=(x<<1)+(x<<3)+ch-'0'; ch=getchar();}
return t*x;
}
struct edge{
int u,v,w,next;
}e[maxp<<1];
void add(int x,int y,int z){ e[++tot]=(edge){ x,y,z,head[x]}; head[x]=tot;}
bool spfa(int x){
memset(dis,0x3f3f3f3f,sizeof(dis)); memset(vis,0,sizeof(vis));
dis[1]=0; vis[1]=1;
queue<int> q; q.push(1);
while(!q.empty()){
int now=q.front(); q.pop(); vis[now]=0;
for(int i=head[now];i;i=e[i].next){
int vv=e[i].v;
if(e[i].w<=mid&&dis[vv]>dis[now]){//注意松弛条件1
dis[vv]=dis[now];
if(!vis[vv]){
vis[vv]=1; q.push(vv);
}
}
if(e[i].w>mid&&dis[vv]>dis[now]+1){//松弛条件2
dis[vv]=dis[now]+1;
if(!vis[vv]){
vis[vv]=1; q.push(vv);
}
}
}
}
return dis[n]<=k;
}
int main(){
n=read(); p=read(); k=read();
for(int i=1;i<=p;i++){
int a=read(),b=read(),c=read();
add(a,b,c); add(b,a,c);
}
li=0,ri=maxl,ans=-1;
while(li<=ri){//二分答案即第k大边
mid=(li+ri)>>1;
if(spfa(mid)) ans=mid,ri=mid-1;
else li=mid+1;
}
printf("%d",ans); return 0;
}
//松弛条件1:当前边权小于二分答案,记为0,然后松弛
//松弛条件2:当前边权大于二分答案,记为1,然后松弛