版权声明:本文为博主原创文章,未经博主允许也可以转载。 https://blog.csdn.net/FrankAx/article/details/82555817
D
题意:找是否存在第k短路且判断长度是否小于等于T。
思路:A*算法裸题。
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int AX = 1e5+66;
const int MAXN = 1e4+66;
int n , m , k;
int s ,t ;
int tot ;
int retot ;
struct edge{
int to , w ;
int next1;
}G[AX] , RG[AX];
//f = g + h
struct Node{
int v;
int f , h , g;
bool operator < ( const Node &a ) const{
if( f == a.f ){
return g > a.g;
}
return f > a.f;
}
};
int dis[MAXN];
int head[MAXN];
int rehead[AX];
int vis[MAXN];
void addedge( int u , int v , int c ){
G[tot].to = v;
G[tot].w = c;
G[tot].next1 = head[u];
head[u] = tot++;
RG[retot].to = u;
RG[retot].w = c;
RG[retot].next1 = rehead[v];
rehead[v] = retot ++;
}
void SPFA(){
for( int i = 1 ; i <= n ; i++ ){
dis[i] = INF;
}
dis[t] = 0;
queue<int>Q;
Q.push(t);
while( !Q.empty() ){
int u = Q.front();
Q.pop();
for( int i = rehead[u] ; ~i ; i = RG[i].next1 ){
int v = RG[i].to ;
int w = RG[i].w ;
if( dis[v] > dis[u] + w ){
dis[v] = dis[u] + w;
Q.push(v);
}
}
}
}
int Astar( Node a ){
memset( vis , 0 ,sizeof(vis) );
if( dis[s] == INF ) return -1;
if( s == t ) k++;
priority_queue<Node>Q;
Q.push(a);
while( !Q.empty() ){
Node tmp = Q.top();
Q.pop();
int v = tmp.v;
vis[v] ++ ;
if( vis[t] == k ) return tmp.g;
for( int i = head[v] ; ~i ; i = G[i].next1 ){
Node p;
p.v = G[i].to;
p.h = dis[G[i].to];
p.g = tmp.g + G[i].w;
p.f = p.g + p.h;
Q.push(p);
}
}
return -1;
}
int main(){
int T;
while( ~scanf("%d%d",&n,&m) ){
scanf("%d%d%d%d",&s,&t,&k,&T);
tot = 0 ;
retot = 0;
memset( head , -1 , sizeof(head) );
memset( rehead , -1 , sizeof(rehead) );
int x , y , w ;
for( int i = 0 ; i < m ; i++ ){
scanf("%d%d%d",&x,&y,&w);
addedge( x , y , w );
}
SPFA();
Node a;
a.v = s ;
a.g = 0;
a.h = dis[s];
a.f = a.g + a.h;
int g = Astar(a);
//printf("%d\n",g);
if( g != -1 && g <= T ){
printf("yareyaredawa\n");
}else{
printf("Whitesnake!\n");
}
}
return 0 ;
}
I
思路:模拟,16进制转2进制,然后奇偶校验,然后根据映射得出结果。
Code:
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
map<char,string> mp;
map<string , int > mp1;
void init(){
mp['0'] ="0000"; mp['1']="0001";mp['2']="0010";mp['3']="0011";mp['4']="0100";mp['5']="0101";mp['6']="0110";mp['7']="0111";mp['8']="1000";mp['9']="1001";mp['A']="1010";mp['B']="1011";mp['C']="1100";mp['D']="1101";mp['E']="1110";mp['F']="1111";
mp['a']="1010";mp['b']="1011";mp['c']="1100";mp['d']="1101";mp['e']="1110";mp['f']="1111";
}
int main(){
int T;
init();
ios_base::sync_with_stdio(false);
cin.tie(0) ; cout.tie(0) ;
cin >> T;
int m , n ;
while( T-- ){
string a;
string b;
string c;
cin >> m >> n ;
mp1.clear();
int asc ;
string s ;
for( int i = 0 ; i < n ; i++ ){
cin >> asc >> s ;
mp1[s] = asc ;
}
b = "";
cin >> a ;
int len = a.size();
for( int i = 0 ; i < len ; i++ ){
b += mp[a[i]];
}
len = b.size();
for( int i = 0 ; i + 8 < len ; i += 9 ){
int num = 0 ;
string tmp = "" ;
int j ;
for( j = i ; j < i + 8 ; j++ ){
if( b[j] == '1' ){
num ++ ;
}
tmp += b[j] ;
}
if( num % 2 ){
if( b[j] == '0' ) c += tmp ;
}else{
if( b[j] == '1' ) c += tmp ;
}
}
int size = c.size() ;
string tmp = "" ;
string res = "" ;
int length = 0 ;
for( int i = 0 ; i < size ; i ++ ){
tmp += c[i] ;
if( length == m ) break ;
if( mp1[tmp] ){
//cout << (char)mp1[tmp];
res += (char)mp1[tmp];
length ++ ;
tmp = "";
}
}
cout << res << endl;
}
return 0 ;
}
K
题意:一个数为素数且任意子串为素数
思路:考虑到答案中任意一位都必须是1或质数,可知答案只可能由1、2、3、5、7构成。由于任意两个不为1的数字构成 的两位数一定可以被11整除,所以答案中除1外的数字只能出现一次;1最多出现2次,因为111可以被3整除;而 2、5、7三者一定不会有两者同时出现。因此满足条件的整数不会超过四位,全部预处理出来即可。
Code:
#include <bits/stdc++.h>
using namespace std;
int a[21]={1,2,3,5,7,11,13,17,23,31,37,53,71,73,113,131,137,173,311,317,10000};
int init(string s){
int cnt = 0;
for(int i=0;i<s.length();i++){
cnt = cnt*10 + s[i]-'0';
}
return cnt;
}
int t;
int main(){
cin>>t;
for(int i=1;i<=t;i++){
string s;
cin>>s;
cout<<"Case #"<<i<<": ";
if(s.length()>=4){
cout<<"317"<<endl;
}else{
int ans = init(s);
for(int i=0;i<21;i++){
if(a[i]>ans){
cout<<a[i-1]<<endl;
break;
}
}
}
}
return 0;
}