2011-11-21训练记录 个人训练(三)

A - DNA Consensus String UVA - 1368

字符串模拟qwq。

#include<bits/stdc++.h>

using namespace std;

const int N = 1010,M = 105;

int t,n,m;
string book[N];

int main(){
	cin >> t;
	while(t --){
		int ans = 0;
		scanf("%d%d",&n,&m);
		for(int i = 1; i <= n; ++i)
			cin >> book[i];
		for(int i = 0; i < m; ++i){
			int a = 0, c = 0, g = 0, t = 0;
			for(int j = 1; j <= n; ++j){
				if(book[j][i] == 'A')	a ++;
				else if(book[j][i] == 'C')	c ++;
				else if(book[j][i] == 'G')	g ++;
				else	t ++;
			}
			if(a >= c && a >= g && a >= t)	putchar('A'), ans += (c + g + t);
			else if(c >= g && c >= t)	putchar('C'), ans += (a + g + t);
			else if(g >= t)	putchar('G'), ans += (c + a + t);
			else	putchar('T'), ans += (c + g + a);
			//printf("a = %d c = %d g = %d t = %d ans = %d\n", a,c,g,t,ans);
		}
		printf("\n%d\n", ans);
	}
	
	return 0;
}

B - Funny Car Racing UVA - 12661

tips:最短路的变形。有n条路m个路口,每个路口有按照固定的周期开启、关闭,通过关卡有一定的时间。问从起点到终点的最短时间。
转化为最短路,通过的时间转化成距离,然后看当前到路口的时候,该路口是开还是关(取模),再考虑通过的时间,得到sum. 用dis[u]+sum来更新dis[j],就是常规最短路的操作了。
坑点:有可能通过路口的时间比该路口开着的时间还长,那么这个路口无法通过!
还是不错的一道最短路变形QWQ

#include<bits/stdc++.h>
#include<queue>
using namespace std;

const int N = 100010;

int h[N], ne[N], open[N], close[N], pass[N], e[N], idx;
int dis[N],n,m,s,t;
bool st[N];

struct HeapNode{
	int u, d;
	bool operator < (const HeapNode& rhs) const{
		return d > rhs.d;
	}
};

void add(int a, int b, int c, int d, int ee){ e[idx] = b, open[idx] = c, close[idx] = d, pass[idx] = ee,ne[idx] = h[a], h[a] = idx ++;}

int Dijkstra(int s){
	memset(dis, 0x3f, sizeof dis);
	dis[s] = 0;
	priority_queue<HeapNode> q;
	q.push(HeapNode{s, 0});
	while(!q.empty()){
		HeapNode fr = q.top(); q.pop();
		int u = fr.u;
		if(st[u])	continue;
		st[u] = true;
		for(int i = h[u]; ~i; i = ne[i]){
			int j = e[i];
			int tmp = dis[u] % (open[i] + close[i]), sum = 0;
			if(pass[i] <= open[i]){
				if(tmp >= 0 && tmp < open[i]){		//现在是开着的 
					if(tmp + pass[i] <= open[i])	sum = pass[i];
					else	sum = pass[i] + open[i] - tmp + close[i];
				}else	sum = pass[i] + close[i] + open[i] - tmp;
				if(dis[j] > dis[u] + sum){
					dis[j] = dis[u] + sum;
					q.push(HeapNode{j, dis[j]}); 
				}
			}
		}
	} 
	return dis[t];
}

int main(){
	int cases = 0;
	while(cin >> n >> m >> s >> t){
		memset(h, -1, sizeof h);
		idx = 0;
		memset(st, 0, sizeof st);
		for(int i = 1; i <= m; ++i){
			int aa,bb,cc,dd,ee;
			cin >> aa >> bb >> cc >> dd >> ee;
			add(aa,bb,cc,dd,ee);
		}
		printf("Case %d: %d\n", ++cases, Dijkstra(s));
	}
	
	return 0;
}

C - Unique Snowflakes UVA - 11572

tips:求最长连续区间长度,该区间没有任何两个相同数字。尺取法。

#include<bits/stdc++.h>

using namespace std;

const int N = 1e7 + 10;

int t,n,book[N];

int main(){
	cin >> t;
	while(t --){
		scanf("%d",&n);
		for(int i = 1; i <= n; ++i)	scanf("%d",&book[i]);
		
		int l = 1, r = 1, ans = 0;
		map<int, int> mp;
		while(true){
			//printf("l = %d r = %d\n", l, r);
			while(r <= n && !mp[book[r]])		mp[book[r++]] ++;
			ans = max(ans, r - l);
			if(r > n)	break;
			mp[book[l++]]--;
		}
		printf("%d\n", ans);
	}
	
	return 0;
} 

D - Updating a Dictionary UVA - 12504

tips:每组给出两个字典,问字典前后的变化(插入?修改?删除?).
非常恶心的字符串模拟,考察vector,map,string的操作。
可以用stringstream简化化简(j代码中的注释部分)。
注意坑点:可能是空字典;可能只有key没有value,这种情况要抛弃。

这种题还是要定期写一写的qwq 非常考验代码能力和细节。

#include<bits/stdc++.h>
#include<map>
#include<vector>
using namespace std;

int t;
char c;
map<string, string> mp1, mp2;
map<string, string> :: iterator it1, it2;
string str;

void make(int flag){
	string s1 = "", s2 = "";
	for(int i = 1; str[i]; ++i){
		c = str[i];
		if(c >= 'a' && c <= 'z')	s1 += c;
		else if(c == ':')	 continue;
		else if(c >= '0' && c <= '9')	s2 += c;
		else if(c == ',' || c == '}'){
			//cout << "s1 " << s1 << " s2 " << s2 << endl;
			if(s1 != "" && s2 != ""){
				if(flag == 1)	mp1[s1] = s2;
				else	mp2[s1] = s2;
				s1 = s2 = "";
			}
		}	
	}
}
/*
void make(int flag) { // 分割得到字典
    for (auto& ch : str) // 将{},:替换为空格
        if (ch == '{' || ch == '}' || ch == ',' || ch == ':') ch = ' ';
    stringstream input(str);
    string sk, sv;
    while (input >> sk >>sv ){
    	if(flag == 1)	 mp1[sk] = sv; // stringstream以空格分割
    	else	mp2[sk] = sv;
	}
}
*/
void judge(){
	vector<string> insert,remove,update;
	vector<string> :: iterator niko;
	bool flag = false;
	for(it1 = mp1.begin(), it2 = mp2.begin(); it1 != mp1.end() && it2 != mp2.end(); ){
		//cout << "1 " << it1->first << " 2 " << it2->first << endl;
		if(it1->first == it2->first){
			if(it1->second != it2->second)	
				update.push_back(it1->first), flag = true; 
			it1 ++, it2 ++;
		}else if(!mp2.count(it1->first)){
			flag = true;
			remove.push_back(it1->first); 
			it1 ++;
		}else if(!mp1.count(it2->first)){
			flag = true;
			insert.push_back(it2->first); 
			it2 ++;
		}
	}
	while(it1 != mp1.end())	remove.push_back(it1->first), it1 ++, flag = true; 
	while(it2 != mp2.end())	insert.push_back(it2->first), it2 ++, flag = true; 
	if(insert.size()){
		printf("+");
		niko = insert.begin();
		cout << *niko;
		for(niko = insert.begin() + 1; niko != insert.end(); ++niko)
			cout << "," << *niko;
		cout << endl;
	}
	if(remove.size()){
		printf("-");
		niko = remove.begin();
		cout << *niko;
		for(niko = remove.begin() + 1; niko != remove.end(); ++niko)
			cout << "," << *niko;
		cout << endl;
	}
	if(update.size()){
		printf("*");
		niko = update.begin();
		cout << *niko;
		for(niko = update.begin() + 1; niko != update.end(); ++niko)
			cout << "," << *niko;
		cout << endl;
	}
	if(!flag)	puts("No changes");
}

int main(){
	cin >> t;
	while(t --){
		mp1.clear(), mp2.clear();
		cin >> str;
		make(1);
		cin >> str;
		make(2);
		judge();
		cout << endl;
	}
	return 0;
}

H - The Counting Problem UVA - 1640

tips:数位DP,统计每个数字出现的次数。

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 25;

int num[N];
ll dp[N][N],l,r;

ll dfs(int pos, bool limit, bool lead,ll sum, int digit){
	if(pos == -1)	return sum;
	if(!limit && !lead && dp[pos][sum] != -1)	return dp[pos][sum];
	int up = limit ? num[pos] : 9;
	ll ans = 0;
	for(int i = 0; i <= up; ++i)
		ans += dfs(pos - 1, (limit && i == up), (lead && i == 0), sum + (i == digit && (i || !lead)), digit);
	if(!limit && !lead)	dp[pos][sum] = ans;
	return ans;
}

ll solve(int x, int digit){
	memset(dp, -1, sizeof dp);
	int pos = 0;
	while(x){
		num[pos ++] = x % 10;
		x /= 10;
	}
	return dfs(pos - 1, true, true, 0, digit);
}

int main(){
	while(~scanf("%lld%lld",&l,&r) && (l && r)){
		if(l > r)	swap(l, r);
		for(int i = 0; i <= 9; ++i)
			printf("%lld%c", solve(r,i) - solve(l - 1, i), (i == 9 ? '\n' : ' '));
	}
	
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值