0
点赞
收藏
分享

微信扫一扫

python每日学习11:numpy库的用法(下)

小桥流水2016 2024-07-30 阅读 30
c++算法ccf

AcWing 3197. 相反数

flag数组标记计数即可 暴力AC: 

#include<iostream>
using namespace std;
const int N=1e3+5;
int n,flag[N],ans;
int main(){
    cin>>n;
    while(n--){
        int x;
        cin>>x;
        flag[abs(x)]++;
    }
    for(int i=1;i<=1000;i++) if(flag[i]==2) ans++;
    cout<<ans<<endl;
    return 0;
}

AcWing 3198. 窗口

模拟 + map AC:

#include<iostream>
#include<cstring>
#include<map>
using namespace std;
typedef pair<int,int>pii;
typedef pair<pii,pii>piiii;
int n,m,flag[2599][1499];
map<int,piiii>mapp;
int main(){
    cin>>n>>m;
    memset(flag,-1,sizeof flag);
    for(int i=1;i<=n;i++){
        int x1,y1,x2,y2;
        cin>>x1>>y1>>x2>>y2;
        mapp[i]=make_pair(make_pair(x1,y1),make_pair(x2,y2));
        for(int j=x1;j<=x2;j++) for(int k=y1;k<=y2;k++) flag[j][k]=i;
    }
    while(m--){
        int x,y,ans;
        cin>>x>>y;
        ans=flag[x][y];
        if(ans>0){
            cout<<ans<<endl;
            piiii t=mapp[ans];
            for(int i=t.first.first;i<=t.second.first;i++)
                for(int j=t.first.second;j<=t.second.second;j++)
                    flag[i][j]=ans;
        }
        else cout<<"IGNORED"<<endl;
    }
    return 0;
}

AcWing 3199. 命令行选项

模拟AC: 

#include<iostream>
#include<map>
#include<vector>
#include<cstring>
using namespace std;
int n,flag_CS[26];// flag_CS用于标记字符是否为命令
int main(){
    string s;
    cin>>s;
    for(int i=0;i<s.size();i++){
        flag_CS[s[i]-'a']=-1;// 将字符标记为无参数命令
        if(s[i]==':') flag_CS[s[i-1]-'a']=1;// 如果字符后有':',标记为有参数命令
    }
    cin>>n;
    getchar();// 吸收换行符,避免影响后续的getline读取
    for(int c=1;c<=n;c++){
        string line;
        getline(cin,line);// 读取一行命令
        vector<string>ans;// 定义字符串向量ans,用于存储分割后的命令
        string t;
        // 分割命令行字符串
        for(int i=0;i<line.size();i++){
            if(line[i]!=' ') t+=line[i];
            if(line[i]==' ') {ans.push_back(t); t="";}
            if(i+1==line.size()) ans.push_back(t);
        }
        map<int,string>mapp;// 定义映射容器mapp,用于存储命令和对应的值
        for(int i=1;i<ans.size();i++){
            // 检查命令格式是否正确
            if(ans[i][0]!='-'||ans[i][1]<'a'||ans[i].size()!=2) break; 
            int x=ans[i][1]-'a';
            // 如果无参数命令
            if(flag_CS[x]==-1) mapp[x]="无参数";
            // 如果有参数命令
            else if(flag_CS[x]==1&&(i+1)<ans.size()) mapp[x]=ans[i+1],i++;
            // 如果命令格式错误,跳出循环
            else break;
        }
        //格式化输出
        cout<<"Case "<<c<<":";
        for(auto x:mapp){
            if(flag_CS[x.first]==-1) cout<<" -"<<(char)('a'+x.first);
            else cout<<" -"<<(char)('a'+x.first)<<" "<<x.second;
        }
        cout<<endl;
    }
    return 0;
}

AcWing 3200. 无线网络

bfs+贪心 AC:

#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
using namespace std;
typedef long long ll;
int n,m,k,r,dist[205][205];//第i个点的路径中增设路由器的数量为j的最短距离
vector<int>G[205];
map<int,pair<int,int>>mapip;
int bfs(){
    memset(dist,0x3f,sizeof dist);
    queue<pair<int,int>>q;
    q.push({1,0});//起点编号为1,初始路由器数量为0
    dist[1][0]=0;
    while(!q.empty()){
        auto t=q.front();
        q.pop();
        int id=t.first,cnt=t.second;
        for(int nextp:G[id]){
            int nextCnt=cnt;
            if(nextp>n) nextCnt++;//如果移动到新增路由器,则计数增加
            if(nextCnt<=k){//如果增设的路由器数量不超过k,则继续搜索
                if(dist[nextp][nextCnt]>dist[id][cnt]+1){//如果找到更短的路径,则更新dist数组,并将新的节点加入队列
                    dist[nextp][nextCnt]=dist[id][cnt]+1;
                    q.push({nextp,nextCnt});
                }
            }
        }
    }
    int ans=0x3f3f3f3f;
    for(int i=0;i<=k;i++) ans=min(ans,dist[2][i]);//终点编号为2  
    return ans-1;
}
int main(){
    cin>>n>>m>>k>>r;
    for(int i=1;i<=n+m;i++){
        int x,y;
        cin>>x>>y;
        mapip[i]=make_pair(x,y);
    }
    for(int i=1;i<=n+m;i++){
        for(int j=i+1;j<=n+m;j++){
            int ax=mapip[i].first,ay=mapip[i].second,bx=mapip[j].first,by=mapip[j].second;
            if((ll)(ax-bx)*(ax-bx)+(ll)(ay-by)*(ay-by)<=(ll)r*r){
                G[i].push_back(j);G[j].push_back(i);
            }
        }
    }
    cout<<bfs()<<endl;
    return 0;
}

AcWing 3201. 任务调度

暴力dfs 超时(4/12):

#include<iostream>
using namespace std;
const int N=45;
int n,flag[N],ans=0x3f3f3f3f;
struct node{
    int a,b,c,d;
}t[N];
void swap(int &a,int &b){
    int temp=a;a=b;b=temp;
}
void dfs(int cnt,int cpu1,int cpu2,int gpu){
    if(cnt==n+1){
        int res=max(max(cpu1,cpu2),gpu);
        if(res<ans){
            ans=res;
            return;
        }
    }
    for(int i=cnt;i<=n;i++){
        // 交换任务顺序
        swap(flag[cnt],flag[i]);
        // 尝试分配到CPU1
        dfs(cnt+1,cpu1+t[flag[cnt]].a,cpu2,gpu);
        // 尝试分配到CPU2
        dfs(cnt+1,cpu1,cpu2+t[flag[cnt]].a,gpu);
        // 尝试分配到GPU,同时更新CPU1和GPU
        int res=max(cpu1,gpu)+t[flag[cnt]].c;
        dfs(cnt+1,res,cpu2,res);
        // 尝试分配到GPU,同时更新CPU2和GPU
        res=max(cpu2,gpu)+t[flag[cnt]].c;
        dfs(cnt+1,cpu1,res,res);
        // 尝试同时分配到CPU1、CPU2和GPU
        res=max(max(cpu1,cpu2),gpu)+t[flag[cnt]].d;
        dfs(cnt+1,res,res,res);
        // 恢复任务顺序
        swap(flag[cnt],flag[i]);
    }
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++) flag[i]=i;
    for(int i=1;i<=n;i++){
        cin>>t[i].a>>t[i].b>>t[i].c>>t[i].d;
        t[i].d=min(t[i].d,t[i].b);
    }
    dfs(1,0,0,0);
    cout<<ans<<endl;
    return 0;
}

考试时候可以写出暴力解法对我来说就很好了...

动态规划 AC:

#include<iostream>
#include<cstring>
using namespace std;
const int N=50, M=210;// N为任务数量上限,M为资源使用上限
int n;
// f[u][i][j][k]表示第u个任务完成后,CPU1使用i个单位时间,CPU2使用j个单位时间,GPU使用k个单位时间的最小完成时间
int f[2][M][M][M];
// c[i][0]为CPU1需求,c[i][1]为GPU需求,c[i][2]为CPU2需求
int c[N][3];
int main(){
    cin >> n;
    // 初始化变量m和m2,用于计算所有任务CPU1需求的总和
    int m=0, m2=0;
    for(int i=1;i<=n;i++){
        int x, y, z, t;
        cin >> x >> y >> z >> t;
        // 存储每个任务的资源需求
        c[i][0] = x, c[i][1] = z, c[i][2] = min(y, t);
        // 累加CPU1的总需求
        m += x;
        // 根据任务编号奇偶性累加CPU1的需求
        if(i % 2) m2 += x;
    }
    // 计算最大可能的CPU1需求,用于确定动态规划数组的大小
    m = max(m2, m - m2);
    // 初始化动态规划数组f,表示初始状态下的完成时间为无穷大
    memset(f, 0x3f, sizeof f);
    // 设置初始状态,没有执行任何任务时的完成时间为0
    f[0][0][0][0] = 0;
    // 遍历每个任务
    for(int u=1;u<=n;u++)
        // 遍历CPU1的可能使用时间
        for(int i=0;i<=m;i++)
            // 遍历CPU2的可能使用时间
            for(int j=i;j<=m;j++)
                // 遍历GPU的可能使用时间
                for(int k=0;k<=j;k++) // GPU不能单独使用,因此k不能大于j
                {  
                    // 获取当前状态下的完成时间
                    int &v = f[u & 1][i][j][k];
                    // 获取当前任务的资源需求
                    int x = c[u][0], y = c[u][1], z = c[u][2], t = (u - 1) & 1;
                    // 尝试不同的分配方案
                    v = f[t][i][j][k] + z;  // 模式3:任务分配给GPU
                    if(i >= x) v = min(v, f[t][min(i - x, j)][max(i - x, j)][k]);  // 模式1:任务分配给CPU1
                    if(j >= x) v = min(v, f[t][min(j - x, i)][max(j - x, i)][k]);  // 模式1:任务分配给CPU2
                    if(i >= y && k >= y) v = min(v, f[t][i - y][j][k - y]);  // 模式2:任务同时分配给CPU1和GPU
                    if(j >= y && k >= y) v = min(v, f[t][i][j - y][k - y]);  // 模式2:任务同时分配给CPU2和GPU
                }
    int ans = 0x3f3f3f3f;
    for(int i=0;i<=m;i++)
        for(int j=i;j<=m;j++)
            for(int k=0;k<=j;k++)
                ans = min(ans, f[n & 1][i][j][k] + max(max(i, j), k));
    cout << ans << endl;;
    return 0;
}
举报

相关推荐

0 条评论